Coping with CSS vendor prefixes

Peter-Paul Koch drops a PPK-bomb on CSS vendor prefixes, the latest post in what seems to be a series of rants which get everyone thinking and talking: not necessarily agreeing. But if you know PPK, then you know that’s probably not the point.

You should read the post. Then form an opinion. Mine is that vendor prefixes are no fun and quite annoying, but a necessary evil. At least for now. There’s no need for me to go into why, as Jonathan Snook makes the point well.

My biggest problem with vendor prefixes is the repetition (read: not the amount of typing), and the fact that I’ll one day need (okay, want) to go back and clean prefixed rules up once they’re no longer necessary or when the implementations change, which they can. I just want a clean style sheet.

A few workarounds, or deal-withs, were mentioned in the comments of the aforementioned posts:

  1. A single “beta” prefix
  2. CSS preprocessors
  3. A separate style sheet

I like the last option the most, hat tip to Bridget Stewart for beating me to it. A separate style sheet fits my current practice of giving each element of design language its own file (I know about the performance implications, but there are plenty of solutions to that). So a generic group of style sheets for a given website might look like this:

  • layout.css
  • type.css
  • color-img.css
  • vendor.css
  • ie[x].css

This is clean. Non-prefixed properties are entered into the normal style sheets, and will (hopefully) be ignored by browsers which don’t understand them. Prefixed properties are placed in vendor.css. And what I would really love is for CSS3, Please! to generate vendor.css for me (That was a hint, guys). Sure, there’s the risk of the spec changing, so it’s up to the designer/developer to be wise in deciding which things should be specified without prefix in the normal style sheets.

Why not the other two?

To be honest, something like -beta- might not be a bad idea, but as of yet, the fact that vendor prefixes are browser-specific is the only useful thing about them. A universal prefix is just that, universal, which could potentially introduce the same problems we would have with no prefixes at all.

I’m not a big fan of CSS preprocessors, or at least I haven’t seen one I’ve liked. We’re talking about CSS; it’s not all that hard to deal with. My problem is not with typing things out three or four times. And I don’t need a preprocessor to do that for me, as prefixes and things like rgba fallbacks are easily accomplished in any decent editor through snippets or scripting. And for those without a decent editor, just use something like CSS3, Please!.

How do you cope?

You only need to subscribe to www-style for about a week before realizing it’s going to take more than three people calling “-beta- prefix!” to get browsers to do it. When you dig down deep enough, there are some very, very smart people who have thought a lot about certain things (and admittedly less about others). It would be a good practice to research or ask why something is as it is, and perhaps participating in www-style and submitting ideas.

You could also try vendor.css. If you hate prefixes, at least you’ve gathered them all together in their own little prefix hell.

How do you deal with vendor prefixes?

A gentle introduction to CSS3 Flexible Box Module (Part 1)

Note: There is no Part 2 to this introduction, as the Flexbox spec has been changed significantly since this post was written. I did, however, write up an introduction to the newer version of the spec, though I couldn’t really call it Part 2.

A portion of what we do as web designers involves arranging elements horizontally or vertically on the screen. As of yet, CSS lacks a suitable mechanism for this task. Enter CSS3 Flexible Box Module (“Flexbox” for short).

Flexbox is one of three W3C draft specs (as of this writing) dealing with general layout issues and has its strengths and weaknesses compared to the other two. But as it has already been implemented in Firefox (and I predict there is a good chance it will be implemented in Safari in some form), you might want to play around with it. Even if it doesn’t get implemented in anything other than Firefox, some of the principles regarding flexible available space have already been injected into the other modules. Plus, it’s pretty fun.

The draft describes Flexbox as:

[...] a CSS box model optimized for interface design. It provides an additional layout system alongside the ones already in CSS. [CSS21] In this new box model, the children of a box are laid out either horizontally or vertically, and unused space can be assigned to a particular child or distributed among the children by assignment of “flex” to the children that should expand. Nesting of these boxes (horizontal inside vertical, or vertical inside horizontal) can be used to build layouts in two dimensions. This model is based on the box model in the XUL user-interface language used for the user interface of many Mozilla-based applications (such as Firefox).

This is pretty clear. It implies two important things:

  1. No more abusing floats, and no more getting abused by floats
  2. We can create true flexible layouts, and the browser will do the calculations for us

Basically, Flexbox is a small part of XUL ported to CSS. Cool as it may be, I remain of the opinion that the power of Flexbox is in the layout of things like UI components (think forms and toolbars and such) rather than in general page layout. So let’s not get carried away and make Flexbox the new float. For general page layout, we need a true grid-based model; I’ll come back to that in the near future. For now, let’s dive in.

Flexbox gives us a new value for the display property (the box value), and eight new properties:

  • box-orient
  • box-flex
  • box-align
  • box-direction
  • box-flex-group
  • box-lines
  • box-ordinal-group
  • box-pack

Today, we’ll ease into this and just focus on box-orient and box-flex, and tackle the other properties in Part 2.

Let’s say we have three paragraphs, each of which introduces one of three product lines for a client website. Our designer has determined that these teaser paragraphs are to be placed adjacent to one another along a horizontal axis, essentially forming three columns.


<div id="products">
    <p id="phones">First child</p>
    <p id="computers">Second child</p>
    <p id="fast-cars">Third child</p>
</div>

How would you currently tackle this? Most, without thinking, would simply float these paragraphs, perhaps adding overflow:hidden; to the parent in order to clear the floats. Nothing very special. But we could also do it quite easily with Flexbox:


#products { 
    display: box;
    box-orient: horizontal;
    }

In the above code, we’re simply telling the parent to behave according to this (flex)box model, and to lay out all its children along the horizontal axis. No floats. Yay.

box-orient accepts four values, but two of them are important for all intents and purposes: horizontal and vertical. Self-explanatory.

The widths of the children remain as specified (or their inherent width if not specified). This means that if the total widths of all the children is less than the total width of the parent, we’ll get something like this:

3 child elements retain their inherent widths within the parent element

But what if you wanted paragraphs one and two to have specific widths and paragraph three to adjust itself depending on the available space within the parent? Flexbox to the rescue:


#products { 
    display: box;
    box-orient: horizontal;
    }
    #fast-cars {
        box-flex: 1;
        }

Here, we’re telling the last child to become flexible, and to take up available space. Since we’ve only allocated space to one element, it will take up all of the available space:

The 3rd child element, having flex, takes up the available space.

Note that the element only becomes flexible along the orientation axis of the box; in this case the element becomes flexible horizontally.

The value for box-flex is relative. So if we were to make the second and third children flexible:


#products { 
    display: box;
    box-orient: horizontal;
    }
    #computers {
        box-flex: 1;
        }
    #fast-cars {
        box-flex: 1;
        }

These would each take up the same amount of available space, in fact dividing the available space equally between them.

2 of the 3 child elements share the available space in the parent element.

Should we give the last child box-flex: 3;, then it would take three times as much available space as the second child.

Check out the demo (this will only work in Firefox) or download the demo source code (.zip-file, 1kB).

Without even considering the other six properties, there are lots of possibilities here. Although I am not in favor of using this module for page layout, it can be done, as you can see in the demo.

We’ll get back to the other properties at a later date. In the meantime, if you want to play around with this, why not? It will only work in Firefox work in Firefox and (newer) webkit browsers; just prefix the display value and properties with -moz- or -webkit- respectively:

  • display: -moz-box;
  • -moz-box-orient
  • -moz-box-flex
  • display: -webkit-box;
  • -webkit-box-orient
  • -webkit-box-flex

Please be advised: this is meant to be a surface-level introduction to a draft spec. At the time of this writing, most people won’t find this applicable to anything outside of experimentation. There is, however, value in learning about the content of somewhat lesser-known working drafts, if only to be able to compare one to another.

Enjoy!

Creative Commons License
A Gentle Introduction to CSS3 Flexible Box Module (Part 1) by Stephen Hay is licensed under a Creative Commons Attribution 3.0 Unported License.