Advanced layout in CSS


Bert Bos | Advanced layout in CSS

Cascading Style Sheets

From level 2 to level 3, experimental new layout features in CSS

Bert Bos (W3C)
Magyarországi Web Konferencia 2008
Budapest, April 26, 2008

About CSS, W3C & me


Screen size

CSS level 2

This presentation is about how we are trying to deal with the problem of increasing screen size, or rather: of the increasing difference between the biggest and the smallest screens. CSS2 was made when all screens were small (and when browsers weren't capable of dealing with complex documents), but now there are screens that can show much more information at once. And it seems CSS needs to acquire some new features.

Problems 1

Screen size

CSS level 2

Problem 1: screen size

“Best viewed with…”?

Desktops and even laptops get bigger all the time. 1600 pixels across and 40 cm is standard. Text lines that long are not readable, it's better to present several things side by side. But the largest smartphones are only 320 pixels and 5 cm across. And even on a big screen, not all the width is for the browser: with a big screen, people view many things at once.

Problem 1 (cont'd)

… viewed on a cellphone

When that page made for a wide screen is viewed on a mobile phone, it doesn't look so readable. The phone is smart enough to reduce the images in size, but it has no other option than to put things that were next to each below one another instead. And thus the page viewed on a phone starts with a long list of images that don't actually serve any purpose, followed at the very bottom by the text that represents the real information on the page.

Problems 2

Screen size

CSS level 2

Problem 2: CSS level 2

Floats are meant for putting images against the margin in a column of text. You can simulate multiple columns with them, but that gets complicated fast. More than three columns and you need to be a wizard…

Positioning is the compromise that came out of an attempt back in 1996 to provide newspaper-like layout capabilities: the page could be divided into a grid and text could be positioned in it. But in 1996 the war was still between FRAME and IFRAME and all that we could save was positioning, without alignment. And thus positioning doesn't really work for complex pages either.

Tables in CSS ('display: table') provide alignment. You can make text boxes that are as high as the box next to it, e.g. But the size is difficult to control, as the algorithms are still based on browser code from 1996 that was never debugged before it was deployed. And, most importantly, tables don't allow elements to be positioned: the order is fixed.

We need features that provide positioning and alignment!


Multiple styles for same page



The solution to these two problems are already under development in CSS. Multiple styles for the same page already works, but we are enhancing the technology to react to different characteristics even within the same class of devices. We have experimental implementations of columns. Grid layout is the least developed so far. We only have a partial protoype. But it is probably also the technology designers are most looking forward to.

Solutions 1

Multiple styles for same page



Media Queries example

[image: small screen and big screen use different

Here is a solution for the problem of different window sizes.

This example is the W3C CSS overview page. It has a two-column layout suitable for a wide range of window sizes. But the design is still too wide for a handheld device. And thus there is a completely different design for those, with only one column and more dense text.

Actually, the slides you are reading are another example. In full screen mode (what CSS calls “projection” mode), the fonts are larger and the decorations are different than in normal “screen” mode.

Media Queries

Media Queries

Different styles for different media

<link rel=stylesheet href=...
  media="screen, print">
@media projection {
  h1 { page-break-before:
	 always }

Simple media queries exist since many years. They are available in HTML, XML and CSS. They are useful for other things than style sheets, too.

The first example above shows a LINK element in HTMl that loads a style sheet only if the browser is running on a normal computer screen or if it is printing.

The second example shows a rule in a style sheet that is protected by a media query: the rule only applies in a browser that is currently making a slide show.

But there are less than a dozen media types available and there is a wide variation of devices within each type, most importantly big screens vs small screens, but also monochrome vs color. So we need more…

Media Queries (cont'd)

Device characteristics

<link rel=stylesheet href=...
  media="screen and (min-width: 45em)">
@media handheld and (monochrome) {
  h1 { color: black } }

These more recent media queries show that certain device characteristics can be mentioned after the media type. In the first example, the style sheet will only be loaded if the browser is currently displaying in a window that is at least 45 em wide.

The second example shows the syntax inside a style sheet. The rule is only applied if the current device is a monochrome, handheld device.

Support for these media queries is (as of April 2008) still not universal, but, e.g., Opera and Apple's iPhone support them partially.

Solutions 2

Multiple styles for same page



Multi-column module

Multiple columns (as in newspaper)

text “snakes” down one column, up to the top,
	then down the next, etc.

… most useful on paper

When the text is long and the rendering surface is wide, the most efficient way to display the text is in columns. The line length remains short enough to be easily readable and yet all the horizontal space is used.

But this works best if the full height of the columns is visible at once, so that the eye can easily find the top of the next column after finishing at the bottom of the previous column. In other words, this works very well on sheets of paper, but not so well on a screen. The chance is high that either the top or the bottom of the column is outside the window and the user has to scroll up and down all the time to read all columns.

Still, this is useful for relatively short texts on wide windows, and, of course, very useful for printing.

Multi-column module (cont'd)

	Multi-column Layout Module

The CSS implementation is very straightforward: the element that is to be displayed in multiple columns gets a proeprty 'columns' to specify either how many columns there should be or how wide the columns are.

There are some additional properties to change the size of the gap between the columns and to put a vertical rule in that gap.

The most difficult part is the 'column-span' property, which allows an element (usually a heading or an image) to span across all columns. It effectively ends the set of columns, displays the spanning elements, and starts a new set of columns.

Solutions 3

Multiple styles for same page



Grid module

3 columns + 2 gaps = 6 grid lines

Columns imply a grid

… number the edges of the grid

… and you have a coordinate system

When you have made columns, it makes sense to use the size of the columns as reference for other things, such as the position or size of images or backgrounds. But that size may depend on various factors and the designer may not know it exactly. The current idea is to introduce a 'gr' unit that represents the width of the current column (or gap between the columns, depending on context).

For positioning, '0gr' represents the left edge (same as '0'), '1gr' represents the right edge of the first column, '2gr' the left edge of the second column, etc. Fractional numbers, such as '1.5gr' or '2.9gr', represent a point interpolated between those edges.

Grid module (cont'd)

CSS Grid
	Positioning Module

img { float: page bottom left;
      width: 3gr }

(float to bottom left, make as wide as 2 columns + 1 gap)

Very early ideas!

We are not yet sure whether the above (floating and then using 'gr' unit for the width) is possible, but it seems worth investigating.

In particular, questions are if the 'gr' unit isn't too confusing and if it is well-defined in all possible contexts.

Template layout module

(Example: A newspaper has a fixed number of columns
	and blocks that span one or more of them.) (Example:
	a Web page for a large screen is like a newspaper page. The designer
	modeled it as a grid of 14 columns.) A grid provides:

Designers are used to working with “grids,&rdquo a system of imaginary horizontal and vertical lines imposed on the page that help to align content. Using the same grid on multiple pages gives unity to the set of pages, especially if the same kind of content is always aligned to the same lines in the grid.

The grid thus serves three purposes: alignment (content forms rows and columns that help to show the structure of a page); positioning (content is positioned according to the design of the grid, rather than in the order in the file; and consistency across pages.

As mentioned above, the alignment idea exists also in the CSS Tables module, but that module doesn't reposition content; and the positioning is available in the Absolute Positioning module, but without the alignment. But we can make a module in CSS level 3 that provides both…

Template layout module (cont'd)

(Example: a page whose body can
	be seen as a grid with 4 columns and 3 rows)
(image © Jina Bolton)

Expressing it in CSS:

To express a grid in CSS, we need a notation in the form of text. Grids are two-dimensional and visual, but we need to describe them linearly. And grids also carry information about their function: some parts of the grid are reserved for images, others for text and others for additional information.

Thus we need to describe where the lines of the grid are and find ways to identify the areas in the grid. Then we need to associate elements in the document with positions in the grid.

Because we are dealing, usually, with variable window sizes, the CSS version of the grid must also define how it reacts to changes in size (something that is not necessary in traditional, paper-based design).

Template layout – describe

	the same page with the implied grid made visible compared to the page itself)
(image © Jina Bolton)

Describe the grid & name the parts:

… let's give them names

The image shows the same page as on the previous slide, but overlaid with the grid lines that the designer used for the layout. The letters indicate distinct areas in the grid. Note that the a and e areas are double the width of the other areas.

We can indicate positions in the grid by numbering the horizontal and vertical edges, as with the 'gr' unit of the previous slides, but naming the slots is even easier and leads to very short notations, as the next slide shows.

Template layout – describe (cont'd)

(Example: the same page with the
	implied grid made visible)
(image © Jina Bolton)

… and in CSS:

    "a a c d"
    "e e g g"
    "i j k l"

We've taken the names (letters) of the areas in the grid and simply written them down as three sequences of four letters, corresponding to the three rows of four columns.

Nothing else is needed in this example, because the columns are all the same width and thus their size is fully determined by the fact that there are four.

If the columns of the grid are not the same width, especially if some are flexible and others are fixed, that information has to be added at the end, after the last line.

Template layout – describe (cont'd)

New design:

(Example: the same page with content arranged
	differently) display:

The same contents can be positioned into a different template. This template has double-width slots on the first row, but not on the second.

The elements are also positioned in a different order. The next slide will show how elements are associated with slots in the template.

In principle, the grid has been turned into a template (hence the name of the module that describes these features) and each slot in the template is indicated by a one-letter name.

Template layout – bind

	Template Layout Module

Bind elements to locations

#intro { position: p }
#maki { position: v }
#sashimi { position: y }

Grid positioning is a form of positioning, except that we don't need the 'top' and 'left' properties to set the coordinates of the element. Instead, we position an element into a named slot in the template.

Multiple elements can be put in the same slot (they will be put one after the other, as if they were sibling elements), and it is also possible to designate one slot as the default, where all elements will go that are not explicitly positioned.

Template layout – properties

Properties of slots:

:slot(r) { background: green }

Because the slots have names, it is relatively easy to give them properties as well. On the other hand, they are not elements, and thus not all properties are easily applied. Giving slots margins, e.g., is difficult to imagine. Ditto for fonts: there would be a conflict between the slot and the element in the slot. But a few properties are easy and useful.

Backgrounds can be positioned behind an element more easily if they can be positioned in the grid, just like foreground elements. The example shows the relevant CSS rule for this.

A slot resembles a table, and thus it is easy to add a 'vertical-align' property with the same function as in table cells.

When a slot in the template has a fixed size, it is possible that the content overflows. The 'overflow' property applies to slots.

The size of rows and columns can be fixed, depend on the available space, or depend on the content of the row/column. The size is added as an annotation after the rows and columns in the expression that defines the names (letters).

The 'gr' unit is also defined for such grid templates, even in the vertical direction.

More info