W3C home > Mailing lists > Public > www-style@w3.org > July 2006

Fwd: A pragmatic approach to page layout in CSS3

From: Nicholas Shanks <contact@nickshanks.com>
Date: Thu, 27 Jul 2006 20:04:28 +0000
To: www-style@w3.org
Message-Id: <9A8B4B69-E496-484C-B713-DBA458E67619@nickshanks.com>
This comes from a friend of mine who doesn't have the self-confidence  
to post it himself, so shall remain nameless, but I thought it was a  
good idea. Basically it's a way of divvying up a page and relocating  
bits of the document presentationally. I leave it with you to discuss.



  During private discussion with acquaintances I devised a means of  
handling basic page layout intended for a forthcoming CSS release. To  
my surprise I was told that CSS3 already has such a means (the  
Advanced Layout Module) but I was rather disappointed to find that it  
was overextended (using it for more than it should be) and tedious  
and fragile -- you have to attach everything into its own cryptically- 
named cell and keep adding more cells to the design.

  So I am presenting here a rough guide to my own, pragmatic  
approach, to see what you think.

  The basic idea starts off similarly to CSS3 with a layout of the  
page, for example:

  @page-structure {
    header h { columns imagecol, sitenavcol };
    columns navleft, maincol { rows intro, bodycell };
    footer; }

  Each top-most element in this list is a row of the page, a block  
box equivalent to a <div>. Each keyword is followed by a comma- 
separated list of named cells. If a cell name is followed by braces,  
the braces contain instructions to subdivide the cell into more rows  
or colums. Like a frameset, cells can only be divided either  
vertically or horizontally, but a cause may be found to generate grids.

  The keywords involved here are:

  * row -- name a row cell that spans the width of the container
  * columns -- name a list of columns
  * rows -- name a list of rows
  * header -- a synonym for row but defines it also to be the header row
  * footer -- a synonym for row but defines it also to be the footer row

  Then, content becomes assigned to cells:

  div#header { locate: intro }
  div#firstsummary { locate: intro }
  div#globalnav { locate: navleft }

  Where multiple block elements are assigned to the same cell,  
assignment is done in order of being read from the CSS or HTML.  
#header will be placed into the intro cell first, followed by  
#firstsummary. This can be overriden such as:

  div#header { locate: intro; locate-params: top }

  will push #header to the top if intro already contains content.  
Content can also be forced to the bottom. Where top or bottom are  
repeated, again, order of reading determines who wins, with most  
recent content favoured.

  Each cell will be a block box which will either be referenced by an  
ID selector (#) or perhaps a new selector, such as '^' (although I  
think we're running out of useful chars ;) Styles applied to a cell  
cascade into enclosed cells just as if they were normal block boxes,  
allowing for a row or column of cells to be styled together.

  In order to maximise flexiblity, it will be crucial that structure  
can be applied in multiple places. For example, /global/styles.css  
may contain:

  @page-structure { rows headercell, main { columns pagenav,  
contentcell }, footercell }; };

  The page itself may decide that inside contentcell, it desires two  
columns:

  #contentcell { structure: columns leftcol, maincol }

  (would nesting braces work in the above? I don't understand all the  
rules enough, I just understand what would make my life substantially  
easier in terms of doing basic, useful two-dimensional layout for  
semantic content)

  Now, pages like <http://telcontar.net/MacApps/HTTPWerkzeug/> could  
be addressed more easily. Supposing the best semantic order for the  
pure HTML was:

  * Title
  * Intro
  * Changes
  * Screenshots
  * Download
  * Version history
  * Credits

  Then the page might contain this CSS to achieve the current layout:

  #screenshots { locate: leftcol }
  #versionhist { locate: leftcol }
  #download { locate: leftcol }

  #title { locate: maincol }
  #intro { locate: maincol }
  #changes { locate: maincol }
  #credits { locate: maincol }

  The above could live in a section CSS for /MacApps/ for all pages  
to share, along with the line that defines the split of the main cell  
into leftcol and maincol.

  This way, the system is a lot less fragile as new cells do not need  
to be created for every last item, and bizarre grids of symbols are  
not needed. Further, cells are not restricted to meaningless single  
character names. I am not sure why I came up with special header and  
footer rows, but in revision, I find them to be rather useless, and a  
waste of identifiers; "row header", where header is defined with  
header-like properties (such as position: fixed), would make more sense.

  The approach of CSS seems typically intended to solve as much as  
possible with as elements as small and fundametal as possible but  
this seems to give rise to unnecessary complication. I intend for my  
design to only handle core page layout and not for unrelated issues  
such as getting forms to look decent.


  Generation of grids for the likes of photo albums always felt  
utterly bogus to me as you're forcing a potentially unsuitable page  
size on the viewport. I much prefer flowing arrangements where the  
cells are all row and column independent and flow as inline boxes.  
This works perfectly in theory but in practice fails for two reasons.  
Firstly, a lack of implementation of inline-block.

  Secondly, a lack of ability for page elements to share common  
derived characteristics. For example, "within this <div>, make every  
inner <div> /* i.e. cell */ be the height of the tallest one". If one  
cell needs its caption to flow to two lines, all cells will have  
their height increase to match so that all the cells will be uniform.  
With tables this only works on a per-row basis but I do not believe  
CSS yet supports this across a whole free-flow grid of inline-block  
boxes.

  I try my best to only ever use flowing arrangements for grids now  
as I am all too aware that careless use of tables (even CSS tables  
when the intention is to define the appearance only) gives you  
horizontal scrollbars and these are as ugly as sin. (I have at least  
two pages where this is a problem but in both cases the overruling  
issue is the lack of inline-block for the moment).


  For lining up forms and definition lists I would suggest using CSS  
tables as they are effectively tabular. Generating huge Advanced  
Layout Module cell grids is horrible as you'd have to keep updating  
the cell list every time you altered the form or definition list and  
hope you never need more than 26 cells (a-z). I imagine there are  
going to be more natural ways to achieve this but I fear they'd be  
too specialised entirely.


Received on Friday, 28 July 2006 09:28:57 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:54:46 GMT