Main content begins here

Blog

Vertical Centering of Tableless HTML Using CSS and jQuery

Intro: 

I've seen other vertical centering techniques and used them successfully, however those techniques only worked for one object. What if you have a list of objects that need vertical centering? This technique is NOT for vertically centering a page, but individual elements such as list items.

I've seen other vertical text centering techniques and used them successfully in certain situations. There seemed to be other situations where I couldn't get the techniques to work. I figured I'd give jQuery a try and see if I could work it out more easily for a group of objects. For my purposes, creating a list of links, I needed to use a fixed height for the <li>.

Final should look something like this:

So you'll need a list. I was making clickable buttons with backgrounds so my HTML/CSS may have more tags than you'll need. I ended up needing some <span> tags inside the <a> tags, such as:

<div class="vertical1">
<ul>
<li><a href="#"><span>Item 1</span></a></li>
<li><a href="#"><span>Item 2 is a little bit longer</span></a></li>
<li><a href="#"><span>Item 3 is ridiculously long. Hopefully it feels more important now that it has used so much space.</span></a></li>
</ul>
</div>

For CSS, use something like the below. I had needed:
.vertical1 ul,
.vertical1 li    {
    margin: 0;
    padding: 0;
    }
.vertical1 li    {
    background: none;
    height: 135px;
    width: 224px;
    position: relative;
    margin-top: 9px;
    }
.vertical1 a    {
    color: #000;
    height: 135px;
    width: 224px;
    display: block;
    background: none orange;
    border: none;
    }
.vertical1 a:hover    {
    background-position: 0 -135px;
    }
.vertical1 span    {
    position: absolute;
    display: block;
    width: 140px;
    margin-left: 15px;
    line-height: 1.1111em;
    font-size: 12px;
    }

You'll need jQuery. Use something like this:
$(".vertical1 li").each(function () {
       li_height = $(this).height();
       span_height = $(this).find("span").height();
       halfway = (li_height/2) - (span_height/2);
       $(this).find("span").css("top", halfway);
    });

Blog terms:

Drupal Jquery JCarousel Implementation

Intro: 

A crazy Drupal jquery jcarousel implementation with some PHP tweaks leads to one crazy-functional project carousel!

A recent project put us in need of a carousel. Jcarousel provided the basics for what we needed however we had to add some additional love to get the carousel working the way the client envisioned.

We had to theme the block.tpl file for the carousel, using PHP to achieve our goal. The biggest issue we needed to address was that the carousel would need to start on the same thumbnail (depending on a page's parent) whether it was on a parent or child page. So even though jcarousel provides a way to start the carousel on a particular thumbnail, we needed a dynamic way to do that since the "home" thumbnail changes throughout the site depending on which project you are on. If you land on Parent A or on anyof Parent A's child pages, the carousel needed to start withProject A's thumbnail.

First we needed to control project parents vs. project children. We used 2 content types for this, with a selector on the child type so we could choose which project parent it belonged to. We added a CCK field to project parents allowing them to choose a carousel ordering.

Next we created a view that pulled the parents as a simple HTML list. Each parent also has a huge background photo, so we used imagecache to create a thumbnail from this for the carousel. The view was shown in a block, whose view-view-list--carousel--block.tpl.php file we themed. We loaded the node form the block:

$nodeid = (arg(0) == 'node' && is_numeric(arg(1)))?arg(1):FALSE;
$node = node_load($nodeid); $nid = $node->nid;

...and depending on the node type there was further code. If it was a child we looked for its parent.

Once we determined the parent (or found out we were already on a parent), we could grab the carousel order from the CCK field of the project we were on so we could tell jcarousel to $start on that item. We also used jquery to provide an active class to the current list item since Drupal wouldn't necessarily do that if were on a child page.

Using the technique above we were able to create a carousel that starts at an appropriate place even if we aren't specifically on that page. As long as we're on any of a project's pages, the carousel starts correctly and we can even style it as such with the addition of an appropriate active class.

You may still be able to see the carousel at QuinnEvans.com in the project section.

Blog terms:

Customize the Ubercart Email Based on Product

Intro: 

Do you need a customized message or bit of text to show on the confirmation email based on one or more of the products purchased?

Let's learn to customize the Ubercart 2 purchase confirmation email based on product. Modifying the message is fairly straightforward, though not the most user-friendly in a Drupally sense.

What I needed was a way to customize text on the email based on what products had been purchased. I imagine this could be something added later to the node itself so that each product could have it's own text blurb added to the email when purchased, or if related to a purchased product, however I needed a quicker solution.

Find the Ubercart Email Template

In your file structure find modules/ubercart/uc_order/templates/customer.itpl.php for editing. At the top of the template add something like:
<?php foreach ($order->products as $product2) {
    if ($product2->nid == 52) { $flag1 = 1; }
    if ($product2->nid == 53) { $flag2 = 1; }
}
?>

You will of course need the "nid" of whatever your product nodes are. An example of this usage would be if you had a sporting goods store that sold products as well as training events like baseball camps. You could use something like this to check to see if the user had purchased a baseball glove and then insert a blurb into the email about upcoming baseball training camps.

In my case I was selling events and wanted a way to remind the user of the directions to the event. Since the events could be held in different buildings and/or rooms we needed to provide text based on the event.

Theming Drupal 5.x, or, How To Thumb-Wrestle Drupal 5 Into Submission and Lay It Low At Your Mighty Feet, Part 3

Intro: 

Oh no... Part 3 may ruffle your feathers after having loved Parts 1 and 2. I apologize in advance.

Parts 1 and 2 revealed some wonderful theming advice however it is now time for the best piece of Drupal 5 theming advice I can give, summed up in a few small words:

Use Drupal 6

Yep, there it is. The best advice I can give is to use Drupal 6. Unfortunately Drupal 6 is no cake walk either, but it is a vast improvement over 5. I am envious of all my client's Drupal 6 sites, as this one os Drupal 5. As amazing as this site was to me when I created it, with all the glory Drupal provides, it's a dinosaur compared to 6.

Blog terms:

Multiple Event Registration Using Drupal & Ubercart Attributes

Intro: 

A quick, easy way to use Ubercart Attributes to enable multiple event registration using Drupal.

Although not as flexible as Webform, we decided to use Ubercart Attributes to enable multiple event registration using Drupal. Here's a quick look into how to use it yourself. We use Drupal 6 the Ubercart 2 module.

This solution may not be suitable if you have advanced needs for information gathering or special user tracking, however if your need is simply to gather some info and allow a user to pay in advance for an event registration, this does the trick.

If you haven't yet, create an Event product class in Ubercart via the "Manage Classes" page (/admin/store/products/classes). Create a test event node we can play with.

In /admin/store/attributes click "add an attribute", for example, "Attendee Name". Choose "text field". Now let's edit your test event node. Near the top of the edit screen is the extra navigation Ubercart adds to product content types ("classes"). Choose "Attributes". Click the "add attributes form" link. You will see a box containing all the Attributes you created earlier. If you only created the one "Attendee Name" attribute then there will only be one attribute in this box. Select it and click the "add attributes" button. This attribute will now show up in your "add to cart" area of the node.

All that remains is some styling and you're all set!

Style Unordered List of Links or Menu with CSS Divider

Intro: 

Find out how to code a list of links appropriately then if needed add a divider with CSS.

In this article we'll discuss creating an unordered list of menu links with a pipe in between, which is an oft-used styling for navigation, particularly in the footer of a site. Of course, feel free to use whatever divider you'd like instead of a pipe, however just know that if you want pure CSS with no image used for the divider, you can only use straight lines and dotted/dashed lines. So for example if you wanted to use the colon symbol (:) for your divider you'd need an image unless you wanted to try the not-so-well-supported :after trick.

I still often see folks coding lists of links with no ul/li structure. Usually they just do something like:
<a href="#">link 1</a> | <a href="#">link 2</a> |<a href="#">link 3</a>

Proper Unordered List Styling

Lists of menu links should always be in list format, because its a list. So it should remain UL/LI format like so:

<ul>
<li><a href="#">item 1</a></li>
<li><a href="#">item 2</a></li>
<li><a href="#">item 3</a></li>
</ul>

In your CSS, apply a background "pipe" image to every LI at the far left and add left padding. Then try a declaration such as: li:first-child {background:none; padding-left:0;} (your real code may vary of course since if you want to target this specific list you will need other classes involved.) This should work in FireFox and IE7/8. Other browsers such as IE6 may require jQuery or other workarounds to listen to the ":first-child" part of the declaration. Your CSS would look something like this:

ul, li { margin: 0; padding: 0; }
li { padding: 0 5px 0 9px; background: url(pipe.gif) 0 .3em no-repeat; list-style-type: none; display: inline; }

UL/LI List CSS Styling Help

You can also do the border-left way suggested above. I offered the pipe option because from years of creating sites I know that often designers do not want the pipe to be the exact height of the list item. This would often lead to extraneous spans just to get the pipe to be the "right" height that the designer wanted (and the client approved). Although a background pipe doesn't scale if the font is resized, it will keep the designers and the clients happy that you "coded it right". If you or your clients aren't picky, the border option is easier and scalable.

On a final note: doing lists this way, as inline, can lead to spacing issues because not all of the space between to items is abolished in this situation. Notice the padding declaration above is uneven (padding: 0 5px 0 9px). To get rid of all the space you'll need to float the <li> instead of changing them to inline. Then you'll need to clear the containing <ul>.

Theming the Date Module for Drupal 5

Intro: 

Getting that finicky Date module to stop printing dates like "07 Apr 2009 - 12 Apr 2009" and start printing them like "7-12 APR 2009"...

WayCoolWebDesign recently had two Drupal web sites in production at the same time that had design goals of using combined event dates. While the default display for dates running more than one day is something like "07 Apr 2009 - 12 Apr 2009" we instead needed the dates to appear shortened as "7-12 APR 2009". While the date module allows for many different lengths of dates I didn't see that this option was offered. It was time for more drastic measures.

Theming the Date Module

While I'm not certain this exactly qualifies as theming since I am not changing display code but rather some functionality. Semantics aside, thank goodness the function used to display the dates is offered as a themable function.

The function you'd look for is the "date_display_combination" function inside "date.theme" file within the Date module. Before adding this function to my template.php file I had used the normal course of choosing pretty short dates within the Drupal functionality, so I knew that dates were set to show something like "07 Apr 2009" before fiddling with the function.

Next I copied the entire function to the template.php file. I then added this block of code right after the point in the function where $date1 and $date2 have been assigned the Drupal-formatted dates (@line 15 or so):

// START:
$jbyear1 = substr($dates['value']['db']['datetime'],0,4);
$jbmonth1 = substr($dates['value']['db']['datetime'],5,2);
$jbyear2 = substr($dates['value2']['db']['datetime'],0,4);
$jbmonth2 = substr($dates['value2']['db']['datetime'],5,2);
$jbday1 = substr($dates['value']['db']['datetime'],8,2);
if (($jbyear1 == $jbyear2) && ($jbmonth1 == $jbmonth2) && ($date1 != $date2)) {
$date1 = $jbday1;
switch($date1) {
case '01': $date1='1'; break;
case '02': $date1='2'; break;
case '03': $date1='3'; break;
case '04': $date1='4'; break;
case '05': $date1='5'; break;
case '06': $date1='6'; break;
case '07': $date1='7'; break;
case '08': $date1='8'; break;
case '09': $date1='9'; break;
default: $date1=$date1; break;
}
}
// END:

More Customization of the Drupal Date Module

I'm not a heavy PHP guy so my code is never elegant. I was not hoping to solve every date issue that may come up, only this particular one. All I was hoping to achieve was that if an event date had more than one day, and the years of both dates were the same, plus the months of both dates were the same, I wanted to combine them. I could see that if Drupal wanted to output "07 Apr 2009" all I need to do was grab the first 2 digits and make that into $date1. Then I ran a switch to get rid of the annoying zero that appears when the date is a single digit 1-9.

After adding this block of code Drupal would now have the first date as a one or two digit number and the second date would be kept as the unaltered second date. Then when combined as normal they'd show the way we intended. The final piece to the puzzle was changing "5-7 Apr 2009" into "5-7 APR 2009" by using CSS text-transform: uppercase.

Blog terms:

Designing & Coding CSS Special Effects

Intro: 

Using CSS for special effects has gotten easier with better browser support for CSS and PNG graphics. Although still painful in IE6, these changes have made special effects more fun to use. Using them requires a little planning though.

Using CSS for special effects has gotten easier with better browser support for CSS and PNG graphics. Although still painful in IE6, these changes have made special effects more fun to use. Using them requires a little planning though.

If you're a true designer for the web you know that web design is not all about a pretty face for a web site. It's about planning. Planning for a user's reactions, planning for content to grow, and on it goes. So in this article we'll talk a bit about planning for and executing special effects. I'll use some real-life examples from sites I've worked on.

Special CSS Effects Using PNGs For Transparency

First up is the Reston Virginia Pet Fiesta. That's right, a party for your pets! In this design I was given a logo, so I based the design on some colours used in the logo, plus the whole fiesta vibe. The background is a sort of stucco feel but that's a fairly mundane repeating background. The special part is the jagged red line between the header and body content, echoing the jagged red line from the hat which the logo animals are wearing.

The first step here was knowing I needed something to dress up the design and to help marry the header with the body content area. Like The Dude's rug in The Big Lebowski, I needed something to tie the room together. I figured a big jagged line echoing the hat would be nice. The problems that went through my head were:

  • do i want to have to cut all those images for where the jagged line overlaps the header and body and left/right columns
  • how will i be able to get this to work with the flash piece that is supposed to show at the top of the body area?

What I decided was that I needed one graphic that had transparency. This way I would not have to cut a bunch of graphics but could instead cut one image that I could layer on top of the design. A GIF was ruled out because I didn't want to have to fuss with getting the jagged line placed EXACTLY right so the edges all matched the various colours it was overlapping, and additionally it probably wouldn't have looked good overlapping the Flash piece. The answer was to use a PNG.

Using PNG and CSS to Achieve Special Effects

Using a PNG meant now I was opening another can of worms because IE6 doesn't support PNG. In order to use them you have to use something like JQuery with PNGFix. This was OK with me because from the beginning I was planning to use JQuery, knowing the shadowed edges of the design would need PNG-power as well.

I went into Illustrator and used a brush to create a fat, irregular-edged but straight line. I then used a filter to make the line jag up and down. I then pasted this as a smart object into Photoshop. Since it remained a vector shape I could resize it without loss of clarity until it looked right in the design. Then I saved out just this jagged line as a PNG.

I created a <div> at the bottom of the HTML template for this design, using CSS to size the div. I placed the jagged line PNG inside the div, then used CSS to position the jag up in the header, overlapping the other design elements including the flash piece. Once the flash was saved out with a transparent background and the wmode was set for its embedding, the jag appears to overlap the flash piece.

2
 

Comments

Say "No" To Multiple Style Sheets

Intro: 

So, I've had enough of the multiple style sheet thing. Actually, I had enough of it when I first heard of it, years ago when it was touted as "the right way" to go about setting up CSS. The premise is this: use one style sheet to set all elements of a browser back to ground zero, often called a "reset" style sheet; use one style sheet for fonts; use one style sheet for colors; use one for other stuff like layout.

UPDATE: January 31, 2010... This article makes reference to the fact I previously needed to use additional style sheets to target certain browsers such as Safari or IE6. I no longer use even these additional style sheets. Instead I use the CSS Browser Selector javascript that allows me to target browsers inside my single CSS stylesheet.

So, I've had enough of the multiple style sheet thing. Actually, I had enough of it when I first heard of it, years ago when it was touted as "the right way" to go about setting up CSS. The premise is this: use one style sheet to set all elements of a browser back to ground zero, often called a "reset" style sheet; use one style sheet for fonts; use one style sheet for colors; use one for other stuff like layout.

Wow, what a pain in the ass. And I mean that from a couple viewpoints -- from having to set it up, to having to maintain it as the original coder, to having to update it as the non-original coder.

When it comes to CSS I do try to do things "the right way" because I realize in the long run some extra work or setup, etc, pays off later. For example a web site doesn't have to be "valid HTML" to run just fine in browsers. Even cross-browser sites don't necessarily "need" to be valid. We do it because it helps down the line in other ways, and because we care about doing things well as an HTML professional.

But this whole multiple style sheet issue is ridiculous. I've worked on projects where "lead" coders have demanded I work a certain way, which I honor because I've accepted the role as subordinate and its therefore a request of my client. I've seen articles from highly respected sites in the industry about multiple style sheets. But I just don't buy it.

Why So Cranky About Multiple Style Sheets?

My reasons are pretty simple. I've been on the side of the person creating those style sheets, and I've been the person who had to edit those style sheets created by others (and even created by me), and I can't possibly fathom how all those style sheets add up to a savings in time. I see strong production value and savings in time and money in using as few style sheets as possible because very simply, it is easier to track down a style to make a change if its all in one style (or as much as possible in one sheet). Multiple style sheets means knowing or searching multiple files for what might be the style you're looking to update. Big waste of time.
I've heard some of the arguments and I just can't agree. It hasn't proven to be a production value to me.

There are times when I HAVE to use separate sheets because I know of no other way to acheive certain goals, such as targeting Safari. In those cases I do have to have separate style sheets.

For your info, although the Way Cool Web Design site does NOT support IE6, you can target certain version of IE by using IE conditional comment like this:
<!--[if IE 6]> <link href="ie6.css" rel="stylesheet" type="text/css" /> <![endif]-->

You can also target Safari by using a malformed style sheet call:
<link type="text/nonsense" rel="stylesheet" href="safari.css" media="all">

The above situations are the some of the only times I use multiple style sheets. So, are you buying into the hype of using multiple style sheets?

Theming Drupal 5.x, or, How To Thumb-Wrestle Drupal 5 Into Submission and Lay It Low At Your Mighty Feet, Part 2

Intro: 

In the land of blind Drupal people, the one-eyed man is Drupal King. I don't know what this means, except now you will know how to theme Drupal 5 so you no longer have to suffer through others' freebie themes. Make your own awesome themes!

In Theming Drupal, Part 1 we talked about some of the basics of the Drupal theme, getting started with your design, code, and the initial steps to creating the theme. Now, as Young MC might say, its time to bust a move.

Your first ally in real theming is the template.php file. This is the place where you override (theme) Drupal's core while maintaining the virgin-freshness of the core itself. If your theme doesn't have a template.php file, add one now. If you're adding one, just add an empty file.

Theming Drupal Regions: Ad, Delete, Mix and Match - More Fun Than Garanimals!

The first thing to notice inside template.php is the regions function: "function themename_regions()". If you don't have this function because you're starting with an empty file, add it now (Garland doesn't have it). It looks something like this:

function mythemename_regions()
{
return array(
"sidebar_left"=>t("left sidebar"),
"sidebar_right"=>t("right sidebar"),
"content"=>t("content area"),
"header"=>t("site header"),
"footer_message"=>t("site footer")
);
}

The regions function allows you to add regions to your design. Be sure each theme's region function is named appropriately. For example in our example from Part 1 the theme is called "my_theme" so the function name will be "function my_theme_regions()".

An example of adding a new region to your theme is, say on the home page you wanted to have a rotating promo. Create a new variable name such as $promo then insert this variable into your page.tpl file like you do any other Drupal snippet such as $content or $sidebar_left. Then in your region function add a new line so we can make the region appear in your blocks for that theme:
"promo"=>t("home page rotating promo")

Creating a Drupal Content Type

Now you'll need to create a new "content type" in Drupal for your home page called "Promo". To do this go to "administer > content management > content types" and choose "add content type". This will be where we store our promos from which we will randomly draw one for display on the home page. Once you create the content type, create a couple dummy promos so you can see this in action when we're done.

Next go to Views and add a Block List View of 1 called "promo_view" with the field of Node:Body, a filter of Published:Yes & Node:Type->"promo", and Sort Criteria: Random. Next visit Blocks where we tell our theme we want the "promo_view" to be placed inside our "promo" region. Shazzam! You have rotating promos. Ain't life grand?

Now I will touch on more customization that I half-promised back in Part 1. It's more template.php magic. That's not magic as in Merlin, it's magic as in Penn & Teller in that I'm gonna show you how it's done. Sort of...

Getting Control of the Drupal Navigation

The default Drupal nav was pretty uninspiring to me at first, back when the only way I knew how to accomplish tasks was hacking core. Naughty, naughty. Now I've learned a few things and I'd like to share them because it is frustrating to a lot of people. That is namely dealing with some navigation customization. Things like adding a selected state to a list item instead of the anchor, adding a span INSIDE the anchor, and enabling a way to allow for using images in the navigation.

I'm not really an intensely learned PHP guy. I can understand most of what's going on and can usually edit existing PHP to achieve a desired outcome, though it may not be the most efficient way, so your mileage may vary, but here is the function I use to spice up my Drupal menus:

function phptemplate_menu_item($mid, $children = '', $leaf = TRUE, $extraclass = '') {
if (menu_get_active_nontask_item() == $mid) {
$class_active = ' selected';
}

if ((menu_in_active_trail($mid)==1)) {
$active_section = ' selectedSection';
}

if($mid) {$mid_id='item'.$mid;}
if($children) {$hasChild=' hasChild';}
else {$hasChild='';}

return $thing.'<li class="'. $mid_id . $active_section . $class_active . $hasChild . ($leaf ? '' : ($children ? ' expanded' : ' collapsed')) . ($extraclass ? ' ' . $extraclass : '') . '">'. menu_item_link($mid, TRUE, $extraclass) . $children . "</li>\n";
}

The above makes a list item (not its anchor) have a "selected" class when active, and its parent will have addionally a "selectedSection" class. This is helpful when you want to control what sections are open/closed using CSS in a menu.

The above also adds an "item#" class such as "item69" to a nav item. People often use an id for this instead of a class but I often have to generate menu items or parts of the menu several times on a page, and muliiple ID usage is improper HTML, so use a class. This is useful if you want to use images for your nav items because you can target specific list items.

The above also adds a "hasChild" class so you can do things such as using an arrow bullet in your nav to indicate which sections have children. You can see this in use on this site by rolling over "Projects" in the main nav to see an arrow indicating that "Industries" has child nodes.

In Part 3 of this series I will continue discussing some template.php magic. Be sure to tune in next time, same Bat Time, same Bat Channel...

John is a great web designer and developer and a pleasure to work with. I wish I had more projects that required John's expertise. He's fast and flexible... what more could you ask for in the web services department? Despite many rounds of edits, far exceeding the scope of work, John remained poised and customer focused, willing to do whatever was needed to deliver the desired final product.
T. J., Senior Manager ENC Marketing & Communications, Inc.
Copyright ©2001-2017 Way Cool Web Design LLC. All Rights Reserved.