Archive for the 'css' Category

Equal-height, 100% height columns with CSS and JavaScript

Friday, January 5th, 2007

Yes, that title was a mouthful. But, you know the idea: you have a CSS-based two-column layout, and you want both columns to always be the exact same height. Maybe you have a narrow left navigation column with a background color (or a gradient) and a wide right content column; if you want that background color to appear for the entire height of your content column, then you’ll need this trick, otherwise, it’ll stop when it reaches the height of its container.

Here’s an example of what we’re looking to achieve in a layout I built at my day job over at TheLadders.com. In this case, the left-hand column has a solid color fading into a gradient at the bottom of our content block. Since the right column will stretch that block down, we need to force the left-column to have the same exact height as the right column. How do we go about doing that?

There are plenty of ways to do make equal height columns using crazy CSS hacks and other methods. They work well, but they’re not very clean. To make it nice and easy, we need to use JavaScript for its main purpose: controlling presentation. And, we’ll only need a few lines of code to do it.

The Set-up
Here’s some example CSS to get that two-column look:

div#container{
  width:800px;
}

div#container div#leftColumn, div#container div#rightColumn{
  float:left;
}

div#container div#leftColumn{
  background-color:#CCC;
  width:250px;
}

div#container div#rightColumn{
  margin-left:50px;
  width:500px;
}

There’s a two-column layout for you. Here’s what that would look like with some example, placeholder content.

The JavaScript
See? That right column extends far past the left column, but we can take care of that with a simple JavaScript function (I had to add a line wrap to fit everything in the page; remove it to actually use the function):

function equalColumns(){
  var l = document.getElementById('leftColumn');
  var r = document.getElementById('rightColumn');

  r.offsetHeight >= l.offsetHeight ? l.style.height =  \\ line wrap
  r.offsetHeight + "px" : r.style.height = l.offsetHeight + "px";
}

Let’s examine what this function does. First, we store references to our two columns. Then, we do the dirty work, using the ternary operator for our comparison. Let’s examine what it’s doing:

  1. offsetHeight is an element’s rendered height, the total height it takes up in the browser window.
  2. If the right column is taller than the left, we set the left column’s CSS style height property to the right column’s height, then add "px" since CSS demands a unit of measure, and offsetHeight is measure in pixels.
  3. What if the left column is taller than right right? We do the same thing: find the left columns offsetHeight in pixels, and assign that to the right column’s CSS height.

Now that we have this function, we’ll add it to window.onload or the body tag’s onload attribute. You can use the addEventListener / attachEvent combination, too. As soon as the body loads, our columns will snap to the same height.

There’s one problem with this little method: if your pages are larger in size you’ll see them finish rendering, the onload event will trigger, and you will see the columns’ height being set (the background image or gradient will jump from its orginal height to its new height). It looks choppy, like you see here.

Can we fix it? Of course! Why run that function onload when you can run it immediately after the columns load in the document?

We’ll move that onload function into a script tag, and place that script tag containing our function immediately after the close tag of our second column. This means that the script will run immediately after that second column loads in the document, and the user will never see anything choppy. The height will be set before content finishes rendering and appears in the browser. Case closed. And, you now have equal columns as seen here. (Unless you’re stuck with using onload?)

But what about that gradient?
If you’ve been looking at the gradient here, you’re probably wondering how that shows up. Well, that’s a topic for another article coming soon. :-) (It’s right here now.)

A Google search can turn up many, many equal height column sites, but, of those I looked at, here’s one of the best (and they have a script modified to take padding into account, something that I didn’t need when I wrote my version for TheLadders).

technorati tags:, , , ,

Stuck with using onload? We can smooth out the height jump by adding a few bits to our CSS and another line to our JavaScript. We’ll change our CSS to:

div#container div#leftColumn{
    width:250px;
}

    div#container div#leftColumn.bg{
        background-color:#CCC;
    }

And, we’ll add a single line to our JavaScript function (and remove that line break I had to add):

function equalColumns(){
  var l = document.getElementById('leftColumn');
  var r = document.getElementById('rightColumn');

  r.offsetHeight >= l.offsetHeight ? l.style.height \\ line wrap
  = r.offsetHeight + "px" : r.style.height = l.offsetHeight + "px";
  l.className = "bg";
}

Now, our background color is applied after the new height is set. This looks much more natural, almost as if a background image is being loaded and applied. If you’re using an image heavy site, odds are users will never notice.

Happy Birthday, CSS!

Wednesday, December 20th, 2006

First of all, sorry that I haven’t posted in a long while. It’s been a big crunch at work, but we’ve cranked out a Brand new homepage. I’m planning on writing up a few articles about the development process and architecture behind it in the few days.

Anyway, this week we celebrate CSS10: Ten Year Anniversary of Cascading Style Sheets (CSS). It’s been 10 big years since CSS debuted. I remember the good old days, when I first started building websites. CSS wasn’t supported at all. Everything used the font tag and its many glorious attributes. If you wanted a background color, you used bgcolor. Margin only worked sporadically on certain elements. In most cases, if it wasn’t a table it wasn’t working.

Now, I only use CSS and can’t remember most of those decprecated properties that I used to rely on to make anything look halfway decent. Tables are back to where they belong, holding data. Here’s to 10 more!

technorati tags:, , ,

Who likes lists?

Tuesday, December 5th, 2006

Positioning lists (ul and ol in HTML-speak) can generally be a huge pain: Mozilla FireFox and Internet Explorer (7, 6, 5 …) both treat lists and list items different: they have different padding, different margins, basically entirely different rendering, and, to top it all off, the list-item-image or list-item-type receive different treatment.

Here’s my "best of all possible solutions" to getting the li portions of your lists to play nicely together. Basically, using a n Internet Explorer conditional comment, give your list items list-style-position:inside and give whatever’s inside your list some padding or text-indent. This won’t get your lists to work the same cross-browser. However, it will let you remove a lot of the extra margin and padding that IE crowds into your list items, making them a little easier to work with. This goes especially true if you’re trying to squeeze them into a tight position.

technorati tags:, , , , ,

CSS Selector Classes on an ID

Tuesday, December 5th, 2006

Want to add a combination of ID and class to a selector? Here’s a nice little piece of CSS. Let’s say you have code like this:

Hello world!

If you want to write a selector based on that element having both that ID and class name in combination (for an even tighter degree of specificity), you can write that selector like so:

div#foo.bar

That CSS selector will match your element. Again, the format is element#id.class.

technorati tags:, , , ,

Here’s an annoying one…

Sunday, November 12th, 2006

This IE6 browser bug shows up if you’re trying to get PNG transparency to show up in Internet Explorer 6 and below using Microsoft’s alpha image filter. What’s the deal? Well, if you’re using that filter on a background-image, then you won’t be able to click on anything appearing above that background-image. Have a form as a child whose parent is using the filter for its background? You won’t be able to click on any of the form elements. At all. The solution? Don’t use a PNG and that filter. It’s not particularly desirable – in fact, it can really mess with your design – but it’s better to leave the filter right out, unless there’s no need to click, highlight, or otherwise interact with an element on the screen.

technorati tags:, , , , , ,

CSS Hacks: You know them, you love them

Thursday, November 9th, 2006

Been looking for an IE7 CSS hack? Been looking for an Opera hack? Odds are, you can find something around here. This is one of the most comprehensive CSS hack sites I’ve seen. By far, the best part is how granular this site gets: just about every browser you’re going to find is covered.

My thoughts on cascading style sheets hacks? Well, since you’ll be using them to correct Internet Explorer’s bad behavior, you should use what Internet Explorer gives you: conditional comments. Use conditional comments to keep IE fixes in a separate CSS file. That’s what I like to do when I have the time: it keeps the "good" code separate from the "bad." Plus, if Microsoft releases any fixes, you need only to adjust the conditional comment; since Microsoft’s conditional comments allow tests against browser version, you’ll be a lot safer with conditional comments. Plus, it keeps your regular stylesheets clean.

If conditional comments aren’t your thing (perhaps because they’re not traditional markup, although they do validate), you can try minimized attribute selectors. Why? Because minimized attribute selectors let you separate IE and Firefox/Opera/Safari CSS selectors into separate blocks. Create an IE block, then "fix" that code in a minimized attribute selector on the line below. This clearly separates IE corrections from compliant code. Unfortunately, these types of selectors aren’t XHTML compliant and are basically out if you’re writing XHTML.

This leads to my final choice, the one I’d probably recommend if conditional comments are out of the picture: exploiting IE’s failure to support media selectors on @import rules. This works almost the same way as conditional comments do, but instead of placing IE code in a separate file, you place compliant code in a separate file, which you then import to correct your IE CSS. Instead of keeping "good" code in your main stylesheet, you use the hack to correct the bad code.

I strongly recommend conditional comments: they’re the cleanest way to render CSS across browsers, and they are flexible enough to allow you to avoid using hacks in your code. If browser compatibility changes, just update the condition. Plus, there’s no nasty hacks that may be corrected in future browser releases hanging around in your stylesheets. But, if the best option isn’t your option, it’s nice to know there are other ways to make your pages render correctly cross-browser.

technorati tags:, , , , , , , , ,

Ajaxian: A flurry of IE DOM toolbars

Wednesday, October 18th, 2006

Ajaxian has a nice little thread on IE DOM toolbars. Originally meant as an intro for DOM Helper, it kind of evolved to incorporate a couple other toolbars. Sure, we all use the FireBug and Web Developer extensions for FireFox, but what do we use for IE?

I personally use Microsoft’s Developer Toolbar, which I was only fairly happy with, mostly due to it’s kind of unintuitive UI. (Yes, floating tooltips are easy to make in .NET applications. No, they are not good as the primary means to communicate data). The Ajaxian article finally prompted me to figure out how to modify the DOM in the IE toolbar (because, apparently, it’s always been possible if hidden). Click on (or otherwise select) an element, and use the middle pane to add and modify attributes.

I’ve been trying to use the right pane, which, to me, seems like it should work (but is apparently only meant to show your element’s current style, which is pretty valuable nonetheless). I especially like how the attribute names are a big, giant dropdown so that you can see them all. With that middle pane, IE’s toolbar is better then the Web Developer extension (more robust), yet still not as great as FireBug. Hopefully, it works in IE 7 right off the bat.

technorati tags:, ,

Whither CSS vertical-align

Thursday, October 12th, 2006

Though there is a CSS property vertical-align, it doesn’t work like attribute valign in HTML tables. CSS property vertical-align doesn’t seem to be able to solve this problem:

Plain and simple, the CSS veritical-align property really doesn’t work like it should. (Maybe it works to the spec, but it’s not intuitive.) It does not work like a <td>’s valign="middle" attribute, and odds are that’s the behavior you’re trying to emulate when you’re using vertical-align.

Aligning an element vertically within a container of a known height is pretty simple. You can:

  • Give the to-be-aligned element margin-top,
  • Give padding-top to the container, an sub-container in the larger container, or the to-be-aligned element,
  • Use position:relative or position:absolute to slide the aligned element into its desired position.

All this is great. But, what happens when you’re trying to vertical-align against something with a dynamic height? Using vertical-align rarely works as planned, and won’t work if you’re using a block-level element. What do you do?

Vertical Centering in CSS is a solid technique that lets vertical alignment work like it should. I’ve got code using this method in production and, let me tell you, it works very well. Yes, it adds a little extra markup to your document and CSS, but it’s well worth it for the final effect: a vertically centered element without the usual headache. Follow that link and align freely!

technorati tags:, ,

12 Ways to Learn - or Improve - Your CSS

Wednesday, September 27th, 2006

As one working exclusively on CSS-based layouts (that’s it, a little markup and a lot of CSS) day in and day out, I readily admit that it’s a tough thing to learn to do and it’s not an easy thing to master. Ben Henick’s 12 Lessons for Those Afraid of CSS and Standards serves both levels by presenting ideas that the novice needs to know and the intermediate needs to master. I recommend clicking that link and reading the article, no matter what you’re level. I’ll provide some of my thoughts on the article below (I’ll even try to make them match his order).

  1. CSS is a very functional language. You really should think of it as an object-oriented language powered by inheritance and contextual properties. This is confusing at first (why does my headline render differently in one column than another?) but immensely powerful (I can make my headline render two different ways in two different contexts).
  2. Rendering engines cause rendering bugs that make perfect presentation of a design very difficult. It’s not impossible, though. Using tools like position, you can really measure and execute designs to the pixel.
  3. Most people don’t understand the skill and time involved in battling browsers, especially when your company or project is firsting starting out down the CSS road. It takes a while – especially for a new CSS programmer – to figure these things out and learn how long "simple" tasks will take.
  4. I’ve fallen into the div-soup trap before. Real CSS mastery occurs when you realize that you don’t need divs anymore, that you can do the same thing using all those "basic" html tags that you’ve long forgotten.
  5. In many cases, the person responsible for a site’s graphic design is not responsible for any other aspects of site implementation. When paired with a failure to create strict site- and section-wide wireframes, this lack of accountability results in unique comps for too many pages, and thus a lot more work for the stylist and producers.

    Please, designers, create consistent designs. There’s no reason why your columns should vary by a few pixels here and there. There’s no reason why a site should have more than a few base templates. Designers can either expidite the build process or bottleneck it with their creations. And, believe me, I’ve designed and built. When I design with building in mind, my design works better with fewer compromises.

  6. Tracking down browser bugs takes time, and it’s most often that crunch time when a project is in its final phases. It’s a hectic thing.
  7. The author left out one big benefit: really taking advantage of the cascade lets you do things, and change things, quickly. Want your left-hand links to be green? Tight CSS makes this a snap.
  8. See #7. You don’t need all the markup that you think. This is a hard concept for novice programmers to grasp: their quickest action is to wrap everything in a div, style it, and walk away. I prefer to use divs as selectors, then use normal HTML markup as children of that selector. This makes stylesheets easy to read and easy to change. Plus, by using normal HTML markup, you can really improve that SEO, which everyone loves.
  9. Without stylesheet hacks, your site won’t work. Plain and simple. Yes, /**/ is not valid CSS, but it works. Try to write code with standards and mind, but avoid blocking on standards. There are cases where you will need to eschew standards to get your work done. Don’t stay late looking for a "standards-compliant fix" when you won’t find one (believe me, I’ve looked), and the hack is the cleaner, easier way to go.
  10. There’s nothing like writing a whole page, getting it into production, then seeing the "peak-a-boo" bug dropping off some text for no discernible reason. Or having blockquotes slowly shift your text off the screen. Or having…
  11. position:relative is usually the first thing I try when trying to fix an IE bug. line-height sometimes works, too.
  12. A background image on an <h1&gt makes a lovely, accessible, SEO-friendly headline. Standard design templates let you use and reuse backgrounds. Reusting common elements means less new browser bugs, and shorter development cycle, and much happier developers.

You can tell I’ve been doing this for a while, eh?

technorati tags:, , , , , , ,

Blogged with Flock

In-depth look at CSS Opacity

Monday, September 18th, 2006

How much could you possibly want to know about CSS opacity? Mandarin Design covers just about all of it here, including a look at how to achieve "Photoshoppy" image and text effects using just CSS.

Here’s the biggest thing to remember when working with opacity? You’ll need to use a couple different flavors of opacity to maintain cross-browser compliance:

  • Firefox lets you use the real deal, opacity and the proper range of 0.0 to 1.0.
  • IE makes you use filter:alpha(opacity=x), where x is a number from 0 to 100 (see-through to fully opaque).
  • Older Mozilla browsers require -moz-opacity, which ranges fom 0.0 to 1.0, like standard opacity

My personal opacity favorites: using opacity on an image to create a CSS-based drop shadow, and using opacity on a large background element to create a transparent overlay on a page. Both give that Photoshop-quality look with pure CSS.

I'm Reading…
Search This Site
You are currently browsing the archives for the css category.

AddThis Feed Button

Need great hosting?

Categories