Thu. April 30, 8:57:25 AM
Love it! I think it's great that javascript developers are pushing css beyond what it is currently capable of. Thanks for introducing me to css template layouts, too.
Updated May 6th: For the longest time I've been waiting for browsers to support the CSS Template Layout module. Today, I found out that Alexis Deveria has given the web community the gift we've all been waiting for. Using JQuery and a plugin we can now take full advantage of the CSS Template Layout Module.
Historically, we've used containers and floats to create our websites but with this method we may possibly be able to make that method history. With template layouts we can finally have source order independence that has plagued the CSS Display: Table, HTML TABLEs and CSS Float techniques. We can also ignore absolute position methods which I've always disliked. Finally the template layout method also handles equal column heights right out of the box.
Template layout works like a grid. We're all familiar with the dozens of CSS libraries that attempt to give designers a grid to work with. I personally despise CSS libraries but that's another story. With template layout we can create all of those complex grids that designers dreamed up with HTML TABLEs, but using only CSS and semantic HTML instead.
The very first thing we'll need to do is import JQuery and the JQuery Template Layout Plugin
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script type="text/javascript" src="http://css-template-layout.googlecode.com/files/jquery.tpl_layout1.1.1.js"></script>
Next we'll need to initialize the plugin using JQuery's document.ready event:
$(document).ready(function()
{
$.setTemplateLayout()
});
The HTML setup can be approached in the same fashion we would approach the old float based layout system. For the sake of this tutorial I've named my DIVs a, b, c, d, e rather than header, nav, content, aside and footer.
<div id="template">
<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="d"></div>
<div id="e"></div>
</div>
We start like we would with any other layout system by centering our main #template DIV and giving it a width. I chose 1000px simply because it's easier to do math with.
#template
{
margin: auto;
width: 1000px;
}
Next we need to assign each of our child DIVs a position name. Again for the sake of this demo I've given each DIV the same position name as it's ID name:
#a { position: a; }
#b { position: b; }
#c { position: c; }
#d { position: d; }
#e { position: e; }
Think of each position name like a variable that will be used to place each DIV in a grid. My code example above would probably look like this in a production environment:
#header { position: a; }
#nav { position: b; }
#content { position: c; }
#aside { position: d; }
#footer { position: e; }
Template Layouts introduces a new CSS pseudo class called ::slot(). Think of slots like a content placeholder. Only certain CSS properties can be applied to slots such as background colors and images.
#template::slot(a) { background: #eee; }
#template::slot(b) { background: #ddd; }
#template::slot(c) { background: #ccc; }
#template::slot(d) { background: #bbb; }
#template::slot(e) { background: #aaa; }
Using our placeholder names we can arrange our DIVs in an equal height grid system using the following syntax:
#template { display: "abcde"; }
We could also easily re-arrange our DIVs by simply ordering the placeholder names like so:
#template { display: "edcba"; }
Note that what we just did is not possible using Sitepoint's evil display: table; method, and is not easily possible using the standard float system. It is possible with absolute positioned elements but
once again we're trying to avoid that.
Until now, I've only shown you the basics of template layouts. I've found that new programming techniques often make little sense until put into a real-world perspective. Lets create a two column template layout:
#template
{
display:
"aa" /150px
"bc"
"dd"
250px 750px
;
}
A break down of that code:
We can easily take our same HTML structure and make it a three column layout with the template layout system:
#template
{
display:
"aaa" /150px
"bcd"
"eee"
* 500px *
;
}
A break down of that code:
The best thing about this approach is we can quickly re-arrange our content in the grid. This might come in handy when displaying content to different media types such as @print and @handheld. Take a look at how easy we could switch our columns around:
#template
{
display:
"aaa" /150px
"dcb"
"eee"
* 500px *
;
}
If ever needed, we could also flip our #header and #footer DIVs like so:
#template
{
display:
"eee" /150px
"dcb"
"aaa"
* 500px *
;
}
I can think of a few reasons not to use this:
Absolutely! While I'm unsure if this is ready for large & complicated designs I think as a community we should start testing this new approach out which is currently in the working draft stage of the W3C spec process.
Love it? Hate it? Speak your mind below...
Tags: css, css3, jquery ( Add Tag )
Love it! I think it's great that javascript developers are pushing css beyond what it is currently capable of. Thanks for introducing me to css template layouts, too.
I would think of a possible contention when it comes to validating the CSS as well - some people are nuts about this ;)
@Aaron: This might validate if you specify in the validator that it's CSS level 3. The great thing about this particular solution is it uses the exact syntax that the W3C uses in their spec. Then the JavaScript parses the CSS and apply the proper styling.
Looks like a nice work-around until the browsers support this natively. Is there any way to make the layout look acceptable with this method in the event that JS is disabled?
Yeah, unfortunately it relies on JavaScript to work which will probably deter enough people from using it. I don't know if I would personally use it on a large site, especially in the site-wide template, but perhaps it could be used on a page level. Without JavaScript enabled it would just show up as a bunch of stacked DIVs.
Yeah, the lack of Progressive Enhancement is sort of a dealbreaker for me... I wonder if there's a way to improve this so that there's some default layout given without Javascript (even if it's not the best).
Also, the layout breaks if you change text size (the divs stay the same height when the text overflows). Is there a jQuery hook to detect text-size changes? If so, you could re-size the divs on text-size change.
Great work though! If these additions could be made, this would be a really useful resource.
Wow, great to see such a thorough introduction to using CSS Template Layouts! Great to see my script encourage use of the module.
A few notes:
- Your demos seem to be making a false assumption, namely that of being able to specify column widths for individual rows. As far as I can tell from the current spec, this is not actually possible. Looks like it partially works with the script, but this is unfortunately due to bad coding on my part. You should only be able to set the widths of all columns, which can be done after all the letter rows have been specified. If you look at the examples on the spec, you should be able to see what I mean.
- I've just released version 1.1 of the script, which fixes some significant bugs. Basically I initially thought of a single element and the slot it flows in as the same thing. This may have been the case in earlier versions of the spec (on which some of the current examples are still based), but is no longer true. Instead, slots can be seen as parent containers for the elements inserted there. There two most important effects of this change are:
1. When you set a column height larger than the content that would appear in it, the elements won't fill it up as before (mostly evident when setting a background). You can, however, set the background for the ::slot() pseudo-elements, which would provide the same effect.
2. When setting widths and heights for template slots, the slots will now accurately have these dimensions, even when elements inside them have padding/borders/margins set. Basically this is a box-sizing issue, and I personally feel this behavior is much more desirable than in was before.
Once again, great stuff. I'll go ahead and add some links to your work for others interested in seeing more demos.
Thanks Alexis! Reading through the W3C specification on Template Layouts is a real challenge. I applaud you for being able to decipher all of their lingo. Just to verify Template Layouts do allow setting the width on individual columns i.e a 175px 500px 175px 3 column layout?
Yeah, it certainly gets a bit confusing here and there. Doesn't help that there's the occasional inconsistancy either!
Certainly possbile, for example:
display:
"aaa" / 1em
"bcd"
"eee" / 1em
175px 500px 175px;
Will give you variable height columns as desired, with header and footer set to a 1em height. I've also updated my demos to be more useful, btw, so you can find more examples there.
it seems like you could have a "down graded" stylesheet that could be referenced if JS was disabled (would required some sort of detection strategy... possibly leveraging a serverside component)
great work all around!
"Layout not triggered until the DOM is loaded." That's the reason why javascript-based solutions won't work ever.
it seems like you could have a "down graded" stylesheet that could be referenced if JS was disabled
@Alexis Thanks! Your old demos were the main reason I wrote this post, just to give people a very basic introduction of template layouts. I checked out your new demos and those are much, much better, especially showing developers real world uses for this technique. I'm going to update my post to adhere to your demos. Keep up the good work Alexis!
@Alexis
How do I use 'link rel=stylesheet .....' with this template ?
Thanks.
@Neil
Could you also shed some light on my question above please?
Thanks.
Linking To External Stylesheet
To anybody trying out the tutorial, an external stylesheet can be used using the 'link rel= ...type=...src=...' . I tried this unsuccessfully until I read the page at code.google.com. The stylesheet filename needs to be also inserted as an argument in setTemplateLayout(). Hope it helps some people.
It worked super untill I added the lightbox2 script code. This messed up the layout completely. Is something special needed to ad other scripts or is it not possible at all?
Christien, Lightbox uses the Prototype Javascript framework, while this technique uses JQuery. You'll need to add some code to your page to make JQuery and Prototype work together.
Amazing resource!
Thank you ever so much - I've tested it in IE6 on Windows XP, resolution 1024 wide, and all seems to be well.
Site Coded And Designed By Neal Grosskopf Using No Crappy CMS Or Themes