CWI and W3C
Kruislaan 413
1098 SJ Amsterdam
The Netherlands
Steven.Pemberton@cwi.nl
www.cwi.nl/~steven
This document is written in XHTML and CSS; while you will be able to read the content acceptably, you need a better browser than the one you are using to see this document properly.
Steven Pemberton is a researcher at the CWI, The Centre for Mathematics and Computer Science, a nationally-funded research centre in Amsterdam, The Netherlands, the first non-military Internet site in Europe.
Steven's research is in interaction, and how the underlying software architecture can support the user. At the end of the 80's he built a style-sheet based hypertext system called Views.
Steven has been involved with the World Wide Web since the beginning. He organised two workshops at the first World Wide Web Conference in 1994, chaired the first W3C Style Sheets workshop, and the first W3C Internationalisation workshop. He was a member of the CSS Working Group from its start, and is a long-time member (now chair) of the HTML Working Group, and co-chair of the XForms Working Group. He is co-author of (amongst other things) HTML 4, CSS, XHTML and XForms.
Steven was until recently Editor-in-Chief of ACM/interactions.
HTML has for too long, and incorrectly, been seen as a purely presentation language. It was originally designed as a structure description language, but extra elements were added later by browser manufacturers in order to influence the presentation. This has had the effect of limiting Web site usability by introducing presentation elements that slow down Web access, reduce or prevent accessibility to the sight-impaired, limit the sorts of devices that may be used to view websites, and reduce the end-user's options when viewing a document.
The World Wide Web Consortium (W3C) started the Style Sheet activity in 1995 in order to get HTML back to its pure form. The result of this was Cascading Style Sheets (CSS), which allows the separation of content and presentation in Web sites.
Using style sheets has many benefits, including:
Even if the Web remained based on HTML, these would be enough reasons to use style sheets. However, the Web is now going in a new direction: XML, and XML has no inherent presentation semantics at all. To use XML you have to use a style sheet to make your site visible.
As a part of the movement to XML, a new version of HTML, called XHTML, is being developed. Since all presentation-oriented elements are being dropped, style sheets will become essential there too.
So the objectives of this course are to give an advanced introduction to the use of CSS to style HTML and XML documents, covering in passing how this can improve usability.
Most attention will be paid to features introduced in CSS level 2
These notes have been produced entirely in XHTML and CSS, using different stylesheets for printing, screen use, and presentation.
It should go without saying that to properly appreciate this document, you have to view it with a browser with good CSS support.
If you can see this text, your browser apparently does not support CSS.
There are many different CSS user agents, and they are not all as good as each other.
While I will be mentioning some shortcomings in some browsers, this is a course on CSS, and not a loving compilation of all the bugs that there are to be found and how to design around them: a course on CSS should have lasting value; a course on which browser has which bugs wouldn't.
CSS implementations are now quite good, but older browsers had a variety of mistakes. Unfortunately, some browser manufacturers want to offer backwards compatibility with those buggy old browsers. So they have two modes: compliant mode, and legacy mode.
To decide which mode to use they look at the document.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
If you want your CSS to work right, always include a DOCTYPE at the head of your document.
XHTML is an XML application: it is XML.
However, it was designed to be sendable to old-fashioned browsers as HTML; the old browsers think they have received HTML, the new ones think they have received XHTML; there are some differences, but in most cases you won't notice them.
So when we say above "For XML it is always in compliant mode", for XHTML we mean "when the browser thinks it has received XHTML and not HTML".
Note that certain HTML-only rules in CSS do not apply to XHTML.
Also remember that HTML is case-insensitive, and XHTML isn't, so a quick way to find out what your browser thinks it has got is the following CSS:
h1 {color: green} H1 {color: red}
HTML was designed so that incorrect documents are corrected by the browser.
However, you can never know exactly how the browser has corrected your document. This means that you don't know the exact structure of your underlying document.
Which means that you can't be sure how your CSS will be applied.
Therefore: always ensure you have a valid document.
For instance, check it at the W3C validator at validator.w3.org
CSS2 added a number of new selectors to CSS, to allow finer selection of elements.
One thing to remember about CSS is that it has a document-order processing model. So several selectors are asymmetric: you can select the first child element, but not the last, you can select the following element, but not the previous, and so on.
*
E > F
E:first-child
E + F
E[att]
E[att="value"]
E[att~="value"]
:hover
:active
:focus
*: selects any element
This is useful for creating rules that are valid for all elements (for instance for a base style sheet that might work with several XML markup languages, where the root element is unknown).
* {color: black; background: white; font-family: sans-serif}
Note that a rule like
*.warning
is equivalent to
.warning
E > F: selects any element F that is a child of E
For instance, these slides are in XHTML, and each slide is just a <div>.
I used to have for each slide
<div class="slide">
but now I can save typing, and have an unadorned <div>. Where I used to have the CSS rule:
div.slide {...}
I now have:
body>div {...}
which only selects divs which are a (direct) child of <body>
Note that the rule
body div
also selects divs that are a child of <body>, but at any level, not just direct children. So if my slides themselves contain <div>s (which they do) then those divs would be selected too.
Another option I could have used was:
body div {... rules intended for slides... } body div div {... rules to undo the above rules ... }
but it is nicer not to have to 'undo' presentation caused by other rules if you can avoid it.
E:first-child: selects any E that is the first child of its parent
So for instance, the following only selects paragraphs that are the first child of their parent:
p:first-child
Note that this slide does not have such a paragraph. The first child is a heading, so the above rule wouldn't apply to any paragraph here.
Usually though you want to be more specific. For instance, to select the first slide of this set:
body > :first-child
which selects any element that is a direct child of <body> that is also a first-child of its parent. Since there is only one of those, the first child of the body, it selects that.
(Sibling = brother or sister)
E + F: selects any F that directly follows an E
For instance, this selects any paragraph that follows another paragraph (i.e., not the first paragraph):
p + p {...}
On this slide I have coloured all such paragraphs red.
This selects any paragraph that follows a paragraph that is the first-child, i.e. the second paragraph:
p:first-child + p {...}
E[att]: any E that has attribute att
For instance, a special selector for paragraphs that have id attributes:
p[id] {color: green}
or any element with an id:
[id] {color: green}or
*[id] {color: green}
(More on this later when we talk about generated content)
a[id]
selects all a elements with an id attribute, while
a [id]
selects all elements that have an id attribute that are a descendent of an a element.
E[att="value"]: where att has exactly the value
Since class selectors like this:
p.warning {color: red}
don't work for generic XML markup, this sort of selector can be used instead:
p[class="warning"] {color: red}
Another example:
a[href="http://www.w3.org/"] { ... styling for 'home' link ... }
E[att~="value"]: where one of the words of att is the value
This is the one you should really use for simulating class selectors, because the class attribute may contain more than one class:
<p class="warning sidebar">... [class~="warning"] {color: red} [class~="sidebar"] {float: left; ... } }
Both of these select the above paragraph.
:hover - selects and element being hovered over (only a link in IE)
:active - selects an 'active' element (button in pressed state, link being retrieved)
:focus - selects an element that has 'focus', e.g. a link that has been tabbed to, a form input that is being typed in.
Note that although most modern browsers support CSS 2, Microsoft Internet Explorer is not a 'modern browser' in this respect. In particular, almost none of the CSS2 selectors work in IE (:hover does).
This means that you can do special effect for other browsers, that IE won't see. For instance:
html>body {... IE won't see these rules ...}
(Look at CSS Zen Garden: Gemination in IE and a modern browser for a surprising example of this)
One use of this difference is to display a warning.
For instance these slides have a warning at the beginning that is only displayed with IE (and other CSS1-only browsers) pointing out to people that they won't see the slides as they are intended. CSS2 browsers don't display the warning.
<p class="csscheck">This document is written in XHTML and CSS2; while you will be able to read the content acceptably, you need a better browser than the one you are using to see this document properly.</p> .csscheck {color: red; font-size: 150%; width: 50%; margin-left: 1em; border: thick red solid} body>div>.csscheck {display: none}
Since the second rule is more specific, its rules override the less-specific set. (i.e., the warning still has a border and so on, but they are just not displayed)
First let's look at an example.
These slides have a structure of a long series of <div>s; each div has a header of some level, usually followed by a paragraph. Write a rule that will convert the first paragraph of a slide to small caps.
Answer.body>div>:first-child+p { font-variant: small-caps }
There are three main ways of positioning in CSS
Other lesser ways of positioning include using vertical-position and using margins. For instance, using margins:
<h1>My life</h1> <p class="author">by Fred Bold</p> p.author {margin-top: -1em; margin-left: 5em}
If you put an image in text, you get the following effect:
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
In other words: a big chunk of whitespace. Float lets the text flow around the image:
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
The difference is due to text-alignment. Here it is aligned right:
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
And here it is justified:
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
You can float anything, not just images. For instance blocks of text.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
This is done by putting the sidebar in a <div
class="sidebar">
, and then using
.sidebar { float: left; width: 30%; background-color: yellow; margin: 0 1em 1em 0}
The nice thing about float is that the floated content stays within the main flow of the document, surrounding text just avoids it automatically.
The only thing you have to take care of is the occasional
clear: both
for following content that must clear the floated content.
Beware of this sort of problem, where the floated object is longer than the text:
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
Relative addressing takes the positioned content and moves it relative to where it would originally have been. It leaves a 'hole' where it would have been:
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
This was done with:
.relative {position: relative; top: 5em; left: 5em}
On the other hand, absolute positioning takes the content out of the flow, moves it, and 'closes up' the gap, as if it had never been there:
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
This was done with:
.absolute {position: absolute; top: 5em; left: 5em}
Note that the heading is moved in relation to an absolute point, not the point where it came from.
In the above examples it looks like relative positioning produced a transparent yellow heading and absolute positioning produced an opaque yellow heading:
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
However, this is just an effect of where in the document the text appears. The text after the relatively positioned heading is later in the document, and so is drawn on the screen later, i.e. over the earlier text. The absolutely positioned heading is also drawn over text that was drawn earlier. This therefore gives the appearance of transparency in one case and opaqueness in the other. Look at the borders above to see this effect more clearly.
In the above examples it looks like relative positioning produced a transparent yellow heading and absolute positioning produced an opaque yellow heading:
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
In this case the relative header has been given a z-index: 2.
If you want to affect such layering explicitely, then you can use the
z-index
property. First let's relatively position some
blocks.
.layer1 { background-color: red; position: relative; top: 2em; left: 2em; } .layer2 { background-color: blue; position: relative; top: 0; left: 0; } .layer3 { background-color: yellow; position: relative; top: -2em; left: 1em; }
Now we can apply the z-index property to the first block to make it be painted last:
.layer1, .layer1t { background-color: red; position: relative; top: 2em; left: 2em; z-index: 1 } .layer2 { background-color: blue; position: relative; top: 0; left: 0; z-index: 1 } .layer3 { background-color: yellow; position: relative; top: -2em; left: 1em; z-index: 1 } .layer1t { z-index: 2 }
Admission: I had to cheat slightly in the slides with an absolutely positioned heading. Absolutely positioned elements are positioned 'absolutely' relative to the closest positioned ancestor element, or otherwise relative to the root element.
So if I had done nothing, the absolutely positioned title in that slide would have appeared somewhere on the first slide. So I positioned all slides relatively, but by (0, 0) so that they didn't move, but so that absolutely positioned elements within them would move within that slide.
So to summarise:
Put another way: when an element is positioned, all its children move with it.
See example. HTML:
<div class="nav"> <h2>Links</h2> <p> <a href="...">Home</a> <a href="...">Away</a> ... </p> </div>
And then in the CSS:
.nav { position: fixed; top: 0; right: 0; width: 6em; ...} .nav a {display: block}
Values: visible, hidden, scroll, auto, inherit
Default: visible
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren.
The basis of hovering is for changing colours or similar. Like this:
a:hover {background-color: yellow}
But it offers more possibilities, such as this: [Hover here]Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
The basis is to have the pop-up text in the element that you are going to hover over:
<span class="popup">[Hover here]<span>Bla bla</span> </span>
Then the default case is to make the pop-up text display: none:
.popup span {display: none}
<span class="popup">[Hover here]<span>Bla bla</span> </span>
Then, when we hover, we make the span visible, and position it as necessary:
.popup:hover span { display: block; width: 10em; background-color: yellow; border: dotted black thin; }
[Hover here]Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
You see that later content is pushed away, because the popup text is being displayed where it is in the content.
<span class="popup">[Hover here]<span>Bla bla</span> </span>
.popup:hover span { display: block; width: 10em; background-color: yellow; border: dotted black thin; position: relative; left: 30%; right: -10em; }
[Hover here rel]Rel Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
You see that later content is pushed away, because the popup text is being displayed where it is in the content, and then moved relative.
<span class="popup">[Hover here]<span>Bla bla</span> </span>
.popup:hover span { display: block; width: 10em; background-color: yellow; border: dotted black thin; position: absolute; left: 30%; top: 12em; }
[Hover here abs]Abs Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
You see that later content is not pushed away, because the popup text is being taken out of the flow.
<span class="popup">[Hover here]<span>Bla bla</span> </span>
.popup:hover span { display: block; width: 10em; background-color: yellow; border: dotted black thin; margin-top: -7em; margin-left: 7em; }
[Hover here margins]Abs Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
You see that later content moves up with the margins of the popup text.
<span class="popup">[Hover here]<span>Bla bla</span> </span>
.popup:hover span { display: block; width: 10em; background-color: yellow; border: dotted black thin; position: fixed; top: 40%; left: 40%; }
[Hover here fixed]Abs Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
You see that later content is not pushed away, because the popup text is being taken out of the flow.
First, let's look at another example (also without images).
A div of class "gallery" contains a number of images; turn them into overlapping thumbnails, and bring them to the top when hovered.
CSS allows you to automatically number elements. For instance, in an alternate stylesheet, these slides are automatically numbered (as you can see if you are looking at the printed version of these slides; the slide numbers are not in the content of the slides). You can use numbering for such things as ordered lists, for numbering headings, or for numbering diagrams or equations.
The first part of the solution is to do with generated content:
p:before {content: "<<< "} p:after {content: " >>>"}
One
Two
Three
Here is a nice trick:
[id]:before { font-size: small; content: "id: " attr(id) " " }
(See the heading of this slide)
The next part of the solution is counters.
ol { counter-reset: item }
ol>li {counter-increment: item }
ol>li:before {content: counter(item) "." }
Counter-reset creates a counter if necessary, and sets it to 0.
Counter-increment creates the counter if necessary, setting it to 0, and then increments it.
Nesting creates a new level of counter. The increment applies then to the most recent one:
<ol> <li> ...... (1) <li> ...... (2) <ol> ... (2,0) <li> ... (2,1) <li> ... (2,2) </ol> <li> ...... (3)
You can generate a list of all the counters with the same name:
li:before {content: counters(item, ".") ": " }
Which will generate something like:
2.2:
You can also do things like
counter-reset: item 20
and
counter-reset: chapter 0 section 0
and
counter-reset: chapter section
as well as
counter-increment: index 10
and
counter-increment: index 10 pointer 5
and
counter-increment: chapter verse
etc.
You can format the counter in different ways:
content: counter(item, lower-latin) ". "
will give i. ii. iii. iv. v. etc.
The second parameter is just the same as available for 'list-style-type':
disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none | inherit
This also works for the 'counters' function:
content: counters(item, ".", upper-latin)
Which will generate things like:
II.II II.III II.IV II.V
counter(item, disc) will format it as a disc and ignore the value.
h2 {counter-increment: chapter; counter-reset: section figure eqn} h2:before {content: "Chapter " counter(chapter) ": " } .eqn {counter-increment: eqn} .eqn:after { content: " ..." counter(chapter) "." counter(eqn) }
E = MC2
Appendixes as well
h2.appendix {counter-increment: appx} h2.appendix:before { content: "Appendix " counter(appx, upper-alpha) ": " }
Which will generate something like:
Appendix A: References
If you have a rule like
p {color: red; color: green}
Then the paragraph will be green; the second property overrides the first.
Similarly with counter-reset
etc. They are properties, just like color
and so on. So, if you have
h2 {counter-reset: chapter; counter-reset: section}
then only section
will be reset! You must use rules like
h2 {counter-reset: chapter section}
1. Number these slides.
2. Number the headings of a document according to level. So the first h1 gets the number 1, the second gets the number 2, etc. The first h2 after the first h1 gets the number 1.1; the second h2 after the first h1 gets number 1.2; the first h2 after the second h1 gets the number 2.1.
1. This is a heading 1.
1.1. This is a heading 2.
1.2. This is a heading 2.
2. This is a heading 1.
2.1. This is a heading 2.
2.2. This is a heading 2.
2.2.1. This is a heading 3.
3. This is a heading 1.
Essentially you have the choice between three different types of image:
Each type has its own advantages and disadvantages, and so the choice of which to use should depend on your needs.
An essential property of each format is that they are compressed: the storage and bandwidth needed is less than for the full image.
But beware: the image gets unpacked once it is used, so it can use much more memory than the compressed size. (One website I visited brought my machine to a crawl, and it turned out that it had a tiny (in bytes) image as background image. But when unpacked it was very large, and used up all my swap space.)
Properties:
This means:
Each pixel is a small number of bits, one for each pixel of the image. The number it represents is an index into the colour map.
The colour map is an array of up to 256 entries, each entry being 24 bits of colour information.
So instead of a million pixels of 24 bits, you have a million pixels of 8 bits, and 256 colour entries of 24 bits. I.e. a little more than 8 million bits instead of 24 million bits.
Pixels (as many as needed, from 1 to 8 bits):
2
104
31
Colour map (up to 256 entries, each 24 bits):
21323567
32767
3312433
Properties:
This means:
Properties of PNG:
This means:
Tiff (7.5k) PNG (6.5k)
JPG (4.7k) GIF (4k)
Low and high compression; 5 kB vs 32 kB
Four gifs: size 941 1000 1102 2367 bytes
These differences are due to the different amount of repetition in the file.
From 256 to 2 colours. File sizes: 30 25 19 14 / 10 7 5 3 kB
An oft-used trick is to make a sort of chess-board style of the pixels in the image, where alternate pixels are transparent. These are all the same image, on different coloured backgrounds:
These three divs have a transparent gif background image. One is a checked pattern of white and transparent, one grey and transparent, and one black and transparent. These three divs have a transparent gif background image. One is a checked pattern of white and transparent, one grey and transparent, and one black and transparent.
These three divs have a transparent gif background image. One is a checked pattern of white and transparent, one grey and transparent, and one black and transparent.
This div contains a PNG image with varying levels of transparency across it. You should see different parts of this text showing through more or less according to the transparency. This div contains a PNG image with varying levels of transparency across it. You should see different parts of this text showing through more or less according to the transparency. This div contains a PNG image with varying levels of transparency across it. You should see different parts of this text showing through more or less according to the transparency.
This div contains a PNG image with varying levels of transparency across it. You should see different parts of this text showing through more or less according to the transparency. This div contains a PNG image with varying levels of transparency across it. You should see different parts of this text showing through more or less according to the transparency. This div contains a PNG image with varying levels of transparency across it. You should see different parts of this text showing through more or less according to the transparency.
A major technique that is used in CSS Zen Garden is of replacing some text with an image.
This has an advantage over traditional uses of images for text, that the text is still in the document so that Google can see it, and so can blind people.
Let's look at an example for replacing a heading with an image:
In the HTML, use a heading, with the text in a span:
<h1><span>Images for headlines</span></h1>
In the CSS, turn off the span:
h1 span {display: none}
and add a background image to the h1
:
h1 { background-image: url(text.gif); background-repeat: no-repeat; background-position: 50% 50% height: 80px; width: 80px; }
There can be some accessibility problems with this technique.
Some screen readers don't see text with 'display: none'.
No one sees anything if images have been turned off.
An alternative technique is to position the 'hidden' text off the screen (note that the span is not necessary):
h1 { text-indent: -100cm; ... }
Another technique is to move something over the top of the text, and then use the background image:
<h1>Images for headlines<span></span></h1> h1 {position: relative} h1 span { position: absolute; top: 0; left: 0; display: block; background-image: ... }
You can use background images to simulate round corners.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum.
.curved { background: transparent url(curve.GIF) no-repeat 50% 0%; width: 211px; padding-top: 8px; font-size: 80%; margin-left: 10% } }
You can use background images to do shadow effects.
Image:
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit. At vero eos et accusam et justo duo dolores et ea rebum.
.shadow { background: transparent url(shadow.png) repeat-y 100% 100%; width: 211px; padding-top: 8px; padding-right: 2em; font-size: 80%; margin-left: 10% } }
Here is an example of 3D effect tabs:
Uses these images:
.tab, .lasttab { display: block; float: left; height: 25px; background: url(tab_end.gif) right no-repeat #ccc; padding: 0 1em 0.25em 1em; .lasttab { background-image: url(tab_end1.gif); } ... <span class="tab">Home</span> <span class="tab">Away</span> <span class="tab">Products</span> <span class="lasttab">Support</span> }
Let's look at another example, also without images.
Make an element that has an image that changes when you hover over it.
One of the big problems with many current web sites is the fixed design.
Part of the problem is that designers have grown up designing for paper, where you have complete control.
On the web, whatever designers may want, you no longer have complete control: you don't know the size of the screen, let alone the size of the window, or even the fonts available, let alone their sizes.
To best serve the interests of the user, you should attempt to utilise the screen real-estate as well as possible.
Here is an example site, luckily now changed, of a site underutilising the
space available:
Here is a site that overuses the space, making it very hard to read. In particular you have to scroll horizontally to read the text.
The aim is to use the space as well as possible.
Don't use pixels for sizes, except for images with an inherent size, because you don't know the resolution of the screen that anyone is using.
For instance, font-size: 12px
will give you
Similarly, avoid using point sizes as well:
Respect these people: try to use relative font sizes. Use font-size: 100% for paragraph text, font-size: 120% or so for headings, font-size: 80% for copyright statements, etc.
... almost every site I go to fails my three-second accessibility test: increasing the size of the type - Steve Krug in Don't Make Me Think (2nd ed)
Similarly, don't use pixels for widths either, for the same reasons
Try whenever possible to express widths as percentages (which refers to the parent element) or as ems (which then refers to the current content.
Good typesetting practise requires you to match your line spacing to the length of the text lines. Long text lines should have wide line spacing, otherwise the reader is likely to get lost when going to the start of the next line.
However, CSS doesn't offer the facility to increase line spacing automatically with line length, so you should therefore restrict the length of your text lines.
But beware: too short lines are unreadable as well.
Solemnly he came forward and mounted the round gunrest. He faced about and blessed gravely thrice the tower, the surrounding country and the awaking mountains. Then, catching sight of Stephen Dedalus, he bent towards him and made rapid crosses in the air, gurgling in his throat and shaking his head. Stephen Dedalus, displeased and sleepy, leaned his arms on the top of the staircase and looked coldly at the shaking gurgling face that blessed him, equine in its length, and at the light untonsured hair, grained and hued like pale oak.
Solemnly he came forward and mounted the round gunrest. He faced about and blessed gravely thrice the tower, the surrounding country and the awaking mountains. Then, catching sight of Stephen Dedalus, he bent towards him and made rapid crosses in the air, gurgling in his throat and shaking his head. Stephen Dedalus, displeased and sleepy, leaned his arms on the top of the staircase and looked coldly at the shaking gurgling face that blessed him, equine in its length, and at the light untonsured hair, grained and hued like pale oak.
Solemnly he came forward and mounted the round gunrest. He faced about and blessed gravely thrice the tower, the surrounding country and the awaking mountains. Then, catching sight of Stephen Dedalus, he bent towards him and made rapid crosses in the air, gurgling in his throat and shaking his head. Stephen Dedalus, displeased and sleepy, leaned his arms on the top of the staircase and looked coldly at the shaking gurgling face that blessed him, equine in its length, and at the light untonsured hair, grained and hued like pale oak.
These two properties allow you to constrain the width within certain bounds. Example:
Widths: this example paragraph has a width of 70%, a max-width of 30em and a min-width of 20em.
There are now more browsers on mobile phones than on PCs.
Web sites seldom cater for small screen browsers, and yet it is so easy.
Use device dependent stylesheets:
<link href="basic.css" rel="stylesheet" media="all" /> <link href="screen.css" rel="stylesheet" media="screen" /> <link href="phone.css" rel="stylesheet" media="handheld" />
or
<style type="text/css" media="handheld">
...
</style>
or
<style type="text/css" media="all"> ... general rules ... @media screen { ... specific rules ... } @media handheld { ... specific rules ... } </style>
Use fluid design.
Make sure you use the correct media values so that your content is usable on handheld devices.
If a handheld understands only media="handheld", then a document with:
<style type="text/css" media="screen">
will have only default styling on the handheld.
This is also true for:
<style type="text/css">
since the default is "screen".
Make sure that you use media="all", or include a stylesheet for media="handheld".
It is quite all right to use point sizes in a print style sheet
Let's look at another example, also without images.
Design a stylesheet for the print version of these slides.
Juxtaposition is stronger than the double bar, and the double bar is stronger than the bar. Thus "a b | c || d e" is equivalent to "[ a b ] | [ c || [ d e]]".
In each definition