Adobe

decor

Web Platform Team Blog

Making the web awesome

Generating Boxes in CSS

CSS Regions allows you to flow content from one box to another in a region chain. One perennial point of discussion on that specification is just where those boxes come from. Our position is strongly inclusive – we think that you should be able to create a region chain out of any box. This could include elements in the regular DOM or Shadow DOM, boxes created from a page template, or boxes created with pseudo-elements or other CSS mechanisms. Back in the CSS Working Group meeting in Hamburg, the group agreed to explore the pseudo-element possibilities.

The initial idea is that you would use pseudo-elements in CSS to define boxes for your region chain. We decided to work on a small incremental step instead of inventing an entirely new pseudo-element for this use case. In current experimental builds of WebKit, you can already use ::before and ::after pseudo-elements as boxes in a region chain. But if you try this, you quickly run up against the limit of only two boxes per HTML element. What if you could make more? Daniel Glazman and I started working on a proposal for multiple ::before and ::after pseudo-elements.

As we worked on the proposal, we found other use cases for breaking the limits on ::before and ::after pseudo-elements. The ::before and ::after pseudo-elements are used today in several ways. These include adding generated content, icons, more borders or backgrounds, and providing a clearfix. If you want to combine more than two of these uses today (or combine these with generating boxes for a region chain) you’re out of luck. With multiple ::before and ::after pseudo-elements you can combine as many of these uses as you wish on a single HTML element.

There are also some cases where separate pieces of generated content should receive separate styling. Think of an academic-journal-style citation. Names, titles, dates and other data needs to be ordered and formatted in a particular manner. With a single pseudo-element you can combine pieces of generated content, but they all get a single style. With multiple pseudo-elements each piece can get its own style block. This use case came up in the discussion Chris Coyier hosted on CSS-Tricks.

In order to get multiple ::before and ::after pseudo-elements in CSS, we needed ways to create, order, and access a list of each pseudo-element type. Our initial ideas ran towards a new generic mechanism in CSS that would work for any pseudo-element type. As we worked on the proposal, Razvan Caliman worked on a prototype where we could all try out each iteration of the syntax. Feedback from the prototype stage and the CSS WG has pushed us towards extending the existing ::before and ::after syntax directly. You can take a look at the current proposal for all the details, but here’s a brief summary:

Adding pseudo-elements uses what we’re calling an “ordinal” – an integer value that says where the particular pseudo-element falls in its list. You can add an ordinal after the regular ::before or ::after syntax to create a new pseudo-element at that ordinal position. An ordinal of ‘1’ is the same as the regular ::before and ::after pseudo-element, and larger ordinals move the pseudo-element farther away in the list from the host element’s content area. The ordinal positions you use do not have to be contiguous.

::before(5)
::before -or- ::before(1)
//content area
::after -or- ::after(1)
::after(3)

You can also access ::before and ::after pseudo-elements by index using syntax like ::nth-before() or ::nth-last-after(). These do not create pseudo-elements, they merely access pseudo-elements already created with the ordinal syntax. In addition to a numerical index, you can also use the an+b syntax from the ::nth-child() pseudo-class. So for the element with two ::before and ::after pseudo-elements in the example above, you could get all of the ::before pseudo elements by asking for ::nth-before(n). Or you can get the innermost ::after element by asking for ::nth-after(1). The tricky bit is that  ::nth-after(2) will get the second ::after element in the list that was created with ordinal 3. The indices run from the content area outwards just as the ordinals do.

Finally, we added a CSSOM section to start the conversation about how pseudo-elements could be exposed to JavaScript. Pseudo-elements and generated content have been a black box to scripting, and this should be fixed. Our discussion of the proposal in San Diego uncovered a more ambitious alternate approach to the one we took, so the current draft mentions both possibilities.

We expect some lively discussion on how this proposal can progress. Hopefully we will come to some agreement on how to extend the facilities in CSS to create more boxes (but not just for region chains). If you are interested in providing feedback for this proposal, please email www-style@w3.org with “[css4-pseudo]” in the subject line.

3 Comments

  1. September 05, 2012 at 9:34 am, Mohamed Moustafa said:

    Just don’t forget the CSS3 properties not available for pseudo-elements, such as transitions and animation.

    • September 05, 2012 at 10:06 am, stearns said:

      Definitely not forgetting those, or other possible pseudo-elements like ::outside. But as I mentioned above, we’re focusing on small, incremental steps right now.

  2. September 07, 2012 at 10:27 am, Brian said:

    Very handy. Thanks so much for the article.. I love the content flow..