Why HCd? Testimonials & Awards Bio: J. Hogue Bio: James Re Studies in [Web] Design HCd>CMS Tutorials Found Thoughts Contact / Location

CSS Tricks: The Amazing Inline-block Property

Comments

J HogueJ. Hogue is a designer for Highchair designhaus, whose website you are viewing. J. has been designing for 12 years and for the web during 5 of those. Occasionally, he likes to throw his hat into the “tricks-and-tips” ring, for which he receives no money and no accolades. Instead, people he will never meet may bookmark this page, and start to execute designs that look cooler than his do. Regardless, feel free to leave a comment if you found this interesting, helpful, or full or erroneous data.

Hello all... while my other tutorials have been targeted at the extremely novice user, this is a cool property that I have been playing with that some of you more experienced coders may or may not have noticed: { display: inline-block; }

The WC3 endorses the use of inline-block, but says very little on how to use it. After some experimenting, I have come up with some nice uses of the property, and it makes multi-column layouts much simpler and cleaner.

First, let’s explore what inline-block is supposed to do... inline elements sit on a baseline like two letters sitting next to each other, like these two letters= XX. If these were two <span>s, they would also sit next to each other along the baseline. In fact, any inline element would co-exist on that baseline alongside another inline element.

Wouldn’t it be great if the Xs were both <div>s and you could make a whole page layout work without floats? With inline-block, that is exactly what you can do. It comes with a price, however, as support in older browsers is spotty. I’ll discuss those caveats as well, and you can decide if it is a tool worth keeping in your arsenal.

Floating DIVs works fine, so what makes inline-block better?

Normally, in order to get two <div>s to sit next to each other, they would need to float left or right, and they would need to have a widths and possibly margins. And in order to get one <div> to contain two more <div>s, you’d have to wrap those two, float the wrapper, and then float the ones inside. When you have all these elements floating around each other, eventually you need to clear a <div> or two to get the background colors to extend down to where they need to be... Well, it works, but it can be messy. All these clear <div>s and extra wrappers to achieve a simple three column layout can be frustrating and bulky.

Even worse, when you need to have two elements next to each other and float: right is the best way to do it, the contents of the <div> floating right needs to be in the markup before anything floating left. This means that in older Blackberrys and other devices that don’t render CSS, they are seeing the content of the page top down, right to left instead of top down, left to right.

So, how can we use inline-block to make multi-column layouts easier?

It’s pretty simple. Use <span>s instead of <div>s, as QuirksMode notes that IE supports the inline-block property as far back as IE6. The trick is that it supports inline-block on an element that normally has a display property of inline. So, this means <span> tags work, whereas applying the inline-block property to a <div> will not work in IE.

In a more perfect world, here is an image diagram of why I think inline-blockis a great property and what it could do to simplify layout in the future.

Addendum

HERE’S THE PROBLEM: A useful property like this comes with a HUGE caveat, however. Because we need to use <span> elements, that means that if we put block-level elements inside of the <span>s, the page will not validate. Block-level elements can not be placed inside inline elements (validator does not take the CSS into account). So, follow the examples below with that in mind. You will have a fully functional page once the browser renders it, but it will not be valid xHTML if you use <span>s.

Until IE 6 and 7 are out of the picture completely, we really can’t in good concience use inline-block they way it could potentially be used, which is really too bad. What I do below in these examples is design for IE 8 and other modern browsers. Some browser-specific hacks are then placed in a conditional IE stylesheet using the star-html hack for IE 6 and the star-plus_html hack for IE 7.

The CSS, HTML and the browser’s display in action:

Here is the code for a two column layout, using classes on span tags and a simple width declaration. We’ll add a border so you can see the elements:

.column { 
	display: inline-block; 
	border: 1px solid #cc3; 
}
.half { width: 49%; }
* html .column { display: block; float: left; }
*+html .column { display: block; float: left; }

<div class="column half">Some content on the left</div>
<div class="column half">Some content on the right</div>

And here is the result:

Some content on the left
Some content on the right

 

Simple... since the two elements are inline, they sit on the same text-baseline. But since they are block as well, they behave like a div normally would, with a width, padding, margins, all that. Now for the vertical-align property.

Think of the way table cells (td’s) need a valign property sometimes, as browsers render their contents center by default. Sometimes, you want the contents of two table cells to align at the top, so that even the short table cell lines up at the top with the longer one. Well, if you think of these spans as table cells, then the vertical-align CSS property is much like the older valign HTML property.

Here’s the same example as above with default vertical alignment displayed by adding more content:

Some content on the left
Some more content on the right. Let’s make this content a little longer so that we can see what happens to the span to the left.

 

Most browsers render the elements with a default vertical-align of “baseline”. The acceptable vertical-align values are baseline, sub, super, top, text-top, middle, bottom, text-bottom, <percentage>, <unit of length> & inherit.

Here is what happens when we define a vertical-align:

.column2 { 
	display: inline-block; 
	vertical-align: top; 
	border: 1px solid #c33; 
}
.half { width: 49%; }

* This effect will not work in IE 6 & 7

Some content on the left
Some more content on the right. Let’s make this content a little longer so that we can see what happens to the span to the left.

 

Ah hah... isn’t that great? Two elements that look like they are floating next to each other, but are actually inline-block elements.

Now we can have some fun...

This starts to get really cool when we use three columns or more. In the example below, notice how the wrapper is automatically the height of the tallest element. No more using a div with a clear: both property before the wrapper closes to get it to stretch it to the right height.

.wrapthedivs { 
	padding: 10px; 
	border: 1px dotted #000; 
}
.column2 { 
	display: inline-block; 
	vertical-align: top; 
	border: 1px solid #c33; 
}
.third { width: 32%; }

 

Some content on the left
Some content in the center. Let’s make this content a little longer so that we can see what happens to the spans on the left and right.
Some more content on the right

 

I decided to use percentages instead of pixel widths in order for the layout to be more flexible. With one class that defines the inline-block and vertical-align properties (.column or .column2) and another class defining the width (.half or .third) I have an array of styles that can be used within any size wrapper. One set of styles that can adjust within wrappers of varying widths. If I need to adjust widths on the fly, I can use a descendent selector to redefine the width (#wrapper .third { new width values } ).

Note:

Percentages are tricky, so you might need to play with how they add up to 100%. You’ll need percentages that add up to less than 100% depending on how you set the margins and padding of the span tags. To help make the look more consistent, it might be a good idea to drop the right padding on the wrapper element to let the natural spacing between the spans play out.

Below is a more fully-fleshed out example with padding and margins:

#wrapthediv2 { 
	padding: 10px 0 10px 5px; 
	border: 1px solid #000; 
}
#wrapthediv3 { 
	padding: 10px 0 10px 5px; 
	border: 1px solid #000; 
	width: 400px; 
}
.column3 { 
	font-size: 12px; 
	display: inline-block; 
	vertical-align: top; 
	border-left: 1px dotted #c33; 
	padding-left: 5px; 
	margin-left: 5px; 
	background-color: #ff9;
}
.column3:first-child { border: none; padding: 0; }
.third2 { width: 31%; }
#wrapthediv3 .third2 { width: 29.5% }

 

With a block-level wrapper, width set to default (auto):

Some content on the left Some content in the center. Let’s make this content a little longer so that we can see what happens to the spans on the left and right. Some more content on the right

 

With a block-level wrapper and a set width. With a descendent selector, I can adjust the percentage to make the spans fit more consistently:

Some content on the left Some content in the center. Let’s make this content a little longer so that we can see what happens to the spans on the left and right. Some more content on the right

 

There you go... Columns made easier with the inline-block property. Fewer wrappers, no “clear divs”, and correct left to right markup order. Use with caution until IE 6 and 7 are marginalized and CSS 3 is standard with its new column properties.

 


 

Blog comments powered by Disqus Notice: Undefined property: StaticPage::$id in /htdocs/content/layouts/studio.php on line 130