When styling fonts with CSS you may be doing this:
font-size: 1em;
line-height: 1.5em;
font-weight: bold;
font-style: italic;
font-variant: small-caps;
font-family: verdana,serif;There's no need though as you can use this CSS shorthand property:
font: 1em/1.5em bold italic small-caps verdana,serif
Much better! Just a couple of words of warning: This CSS shorthand version will only work if you're specifying both the font-size and the font-family. Also, if you don't specify the font-weight, font-style, or font-varient then these values will automatically default to a value of normal, so do bear this in mind too.
Usually attributes are assigned just one class, but this doesn't mean that that's all you're allowed. In reality, you can assign as many classes as you like! For example:
<p class="text side">...</p>
Using these two classes together (separated by a space, not with a comma) means that the paragraph calls up the rules assigned to both text and side. If any rules overlap between the two classes then the class which is below the other in the CSS document will take precedence.
When writing a border rule you'll usually specify the colour, width and style (in any order). For example, border: 3px solid #000 will give you a black solid border, 3px thick. However the only required value here is the border style.
If you were to write just border: solid then the defaults for that border will be used. But what defaults? Well, the default width for a border is medium (equivalent to about 3 to 4px) and the default colour is that of the text colour within that border. If either of these are what you want for the border then you can leave them out of the CSS rule!
Normally in CSS whichever rule is specified last takes precedence. However if you use !important after a command then this CSS command will take precedence regardless of what appears after it. This is true for all browsers except IE. An example of this would be:
margin-top: 3.5em !important; margin-top: 2em
So, the top margin will be set to 3.5em for all browsers except IE, which will have a top margin of 2em. This can sometimes come in useful, especially when using relative margins (such as in this example) as these can display slightly differently between IE and other browsers.
(Many of you may also be aware of the CSS child selector, the contents of which IE ignores.)
It's always advisable to use regular HTML markup to display text, as opposed to an image. Doing so allows for a faster download speed and has accessibility benefits. However, if you've absolutely got your heart set on using a certain font and your site visitors are unlikely to have that font on their computers, then really you've got no choice but to use an image.
Say for example, you wanted the top heading of each page to be ‘Buy widgets’, as you're a widget seller and you'd like to be found for this phrase in the search engines. You're pretty set on it being an obscure font so you need to use an image:
<h1><img src="widget-image.gif" alt="Buy widgets" /></h1>
This is OK but there's strong evidence to suggest that search engines don't assign as much importance to alt text as they do real text (because so many webmasters use the alt text to cram in keywords). So, an alternative would be:
<h1><span>Buy widgets</span></h1>
Now, this obviously won't use your obscure font. To fix this problem place these commands in your CSS document:
h1
{
background: url(widget-image.gif) no-repeat;
}
h1 span
{
position: absolute;
left:-2000px;
}The image, with your fancy font, will now display and the regular text will be safely out of the way, positioned 2000px to the left of the screen thanks to our CSS rule.
The box model hack is used to fix a rendering problem in pre-IE 6 browsers, where by the border and padding are included in the width of an element, as opposed to added on. For example, when specifying the dimensions of a container you might use the following CSS rule:
#box
{
width: 100px;
border: 5px;
padding: 20px;
}This CSS rule would be applied to:
<div id="box">...</div>
This means that the total width of the box is 150px (100px width + two 5px borders + two 20px paddings) in all browsers except pre-IE 6 versions. In these browsers the total width would be just 100px, with the padding and border widths being incorporated into this width. The box model hack can be used to fix this, but this can get really messy.
A simple alternative is to use this CSS:
#box
{
width: 150px;
}
#box div
{
border: 5px;
padding: 20px;
}And the new HTML would be:
<div id="box"><strong><div></strong>...<strong></div></strong></div>
Perfect! Now the box width will always be 150px, regardless of the browser!
Say you wanted to have a fixed width layout website, and the content floated in the middle of the screen. You can use the following CSS command:
#content
{
width: 700px;
margin: 0 auto;
}You would then enclose <div id="content"> around every item in the body of the HTML document and it'll be given an automatic margin on both its left and right, ensuring that it's always placed in the centre of the screen. Simple... well not quite - we've still got the pre-IE 6 versions to worry about, as these browsers won't centre align the element with this CSS command. You'll have to change the CSS rules:
body
{
<strong>text-align: center</strong>;
}
#content
{
<strong>text-align: left</strong>;
width: 700px;
margin: 0 auto;
}This will then centre align the main content, but it'll also centre align the text! To offset the second, probably undesired, effect we inserted text-align: left into the content div.
Vertically aligning with tables was a doddle. To make cell content line up in the middle of a cell you would use vertical-align: middle. This doesn't really work with a CSS layout. Say you have a navigation menu item whose height is assigned 2em and you insert this vertical align command into the CSS rule. It basically won't make a difference and the text will be pushed to the top of the box.
Hmmm... not the desired effect. The solution? Specify the line height to be the same as the height of the box itself in the CSS. In this instance, the box is 2em high, so we would insert line-height: 2em into the CSS rule and the text now floats in the middle of the box - perfect!
One of the best things about CSS is that you can position an object absolutely anywhere you want in the document. It's also possible (and often desirable) to position objects within a container. It's simple to do too. Simply assign the following CSS rule to the container:
#container
{
position: relative;
}Now any element within this container will be positioned relative to it. Say you had this HTML structure:
<div id="container"><div id="navigation">...</div></div>
To position the navigation exactly 30px from the left and 5px from the top of the container box, you could use these CSS commands:
#navigation
{
position: absolute;
left: 30px;
top: 5px;
}Perfect! In this particular example, you could of course also use margin: 5px 0 0 30px, but there are some cases where it's preferable to use positioning.
One of the disadvantages of CSS is its inability to be controlled vertically, causing one particular problem which a table layout doesn't suffer from. Say you have a column running down the left side of the page, which contains site navigation. The page has a white background, but you want this left column to have a blue background. Simple, you assign it the appropriate CSS rule:
#navigation
{
background: blue;
width: 150px;
}Just one problem though: Because the navigation items don't continue all the way to the bottom of the screen, neither does the background colour. The blue background colour is being cut off half way down the page, ruining your great design. What can you do!?
Unfortunately the only solution to this is to cheat, and assign the body a background image of exactly the same colour and width as the left column. You would use this CSS command:
body
{
background: url(blue-image.gif) 0 0 repeat-y;
}This image that you place in the background should be exactly 150px wide and the same blue colour as the background of the left column. The disadvantage of using this method is that you can't express the left column in terms of em, as if the user resizes text and the column expands, it's background colour won't.
At the time of writing though, this is the only solution to this particular problem so the left column will have to be expressed in px if you want it to have a different background colour to the rest of the page.
Comments
Not many news there but a good list
However, I do strongly advise not to advertise the IE !important bug as a mean to cater browser specific styles. !important is an Accessibility feature of CSS and not a designer toy.
When it comes to vertically aligning with CSS we should also point out that there is a way to align a whole element vertically, not only inline text.
A couple notes about Tip #5
This is one of many, many image replacement techniques out there. The one mentioned in the article is missing an essential property. You must set the height of the <h1> element equal to the height of the image.
Also noteworthy is the fact that depending on colors, backgrounds, and browsers, you may see a horizontal line across the screen where the element falls due to the negative positioning. I personally prefer simply to give the span element a “display: none” style.
Display:none
corrections
Don't forget that IE has issues handling multiple classes.
#5Why in the world would you add a
<span>there? You can accomplish the same thing with:<h1>Buy widgets</h1> h1 { background: url(widget-image.gif) no-repeat; text-indent: -2000px; }#6Don't butcher the markup so that you can clean up presentation hacks...that's just rediculous. Content stays the same, presentation is what you're changing, so put the hacks in the presentation.
#7While that's fine for content within
<body>, if, as per your example, you're making the whole of<body>700px wide, the following is what you should use, instead of adding a useless and unnecessary<div>:body { width: 700px; margin: 0 auto; }Better IE hack
One more tip
Excellent article! I would add just one more tip - you can style elements twice to save repeated lines of code in your stylesheets. To do this you rely on the cascade. (What's styled first gets over-ruled by later styles.) Here's an example:
Say you have three identical divs with each one looking like this:
#div1 { position:absolute; top:0; left:100px; width:100px; height:200px; margin:0; padding:0; background-color:red; }The only difference in my example between the divs is their left position and background colour. So why waste bytes styling each one in the same way? Simply style all the divs in one go, then style the differences afterwards. You can save enormous amounts of code this way! Eg:
#div1, #div2, #div3 { position:absolute; top:0; left:100px; width:100px; height:200px; margin:0; padding:0; background-color:red; } #div2 { left:200px; background-color:green; } #div3 { left:300px; background-color:yellow; }Watch those typos - bad for newbies
Contextual selectors
I've found contextual selectors to be very useful. For example, if I have two divs I can assign an id to each of them and style any paragraphs or headings differently, depending on which div they sit in.
For example, I have a div with an id of "middle" which defines the middle column of a page. The other div - "right" - defines the right hand side column. I set up the contextual selectors to apply a different style to the paragraphs, depending on which div it sits in.
I can then use paragraph tags and header tags without applying any classes to them. This is great for content management as the content can be picked up and placed anywhere - offering a nice amount of flexibility. It's also good for a contribution approach to content management as people in the business only need to supply semantically marked up content - the styling is applied depending on which part of the page or site the content goes in.
This approach also makes it easier to redesign as you don't have to think about which classes have been assigned to which element. The content is clean, semantic code which can be used anywhere (including being syndicated to third parties).
paulnattress
codepo8
I agree with your advice about naming the columns (the above was just a quick example). Names such as "mainbodycontent" and "righthandcontextualcontent" would be better.
More
Also you can give the BODY tag an ID for pages using similar styles but with one or two differences. Then you can just add a few relevant lines of code to match the ID, meaning you don't need a whole new stylesheet.
I learned a lot
I really learned a lot from your article. Thank you for posting it. Some of these guys are really rough on you, but I'm learning from their comments as well. Thanks again.
Great article ? About a french translation ?
On Tip #9
About !important
Tantek Celik Critiques
You might be interested to know that Tantek Celik has written up a critique of this article on his site.
Overall he says that it's not a bad article, but he does correct some errors and shortcomings in a couple of the points.
Typos
[Edit: good points, added the semicolons. Absolute in this case refers to the relative element, this is exactly what the trick is about :-)]
Re. "On Tip #9" Absolute versus Relative
CSS Shorthands
Forcing Scrollbar
overflow: -moz-scrollbars-vertical;
I must admit, that i've tested it only with mozilla, since i have no other browsers at my hands currently. Maybe this is helpful to some of ya :)
best regards,
Stefan_K
--
My first site :) (quite ugly. but hey, that was my first site ever, hehe)
Proprietry CSS is never a good idea
Interesting article for me
I'm amazed at the negative tone of some of these comments. As a sub-expert level page designer, I find any suggestions for solving the myriad problems created by unruly browsers and an as-yet incomplete CSS spec are useful, and the ones here are just that. Not perfect, obviously, but helpful nonetheless. Do agree about the raspberry for the typos though: THAT can be frustrating.
Not well tested.
Read the article. Read Tantek's critique.
Tantek's comments are right on. The image replacement is only good for text browsers.. useless to screen readers. Screen readers wont read the content that's positioned off screen. They will however read content with a negative text-indent. A simple test would have showed this. So -1 on that tip.
I would expect a better review from Evolt. This article should probably have been regected untill the potentially harmfull tips were fixed.
#7 Centre aligning a block element
...some more comments for you
box model hack ?
I am designing my first page completely without tables and during my coding i was frustrated about the crossbrowser problems. Especially the box model problem makes me totaly nervous.
Now my observations on tanteks model hack. I tryed it a along time in every diferent way but it won't work with my Opera Version 7.23 and my IE 6.0.28. IE isn't ignoring the "\"}\"" value and Opera also subtracts the border-width, padding and margin from the container width.
Please don't watch my Typos too exactly. I knew that my english is not the best.
Correction: box model hack ?
Correction: box model hack ?
Shit happens!
Code before and after:
Very handy to have all these tips in one place
Background colour running to the screen bottom
I actually came up with a solution to work with percentage and em width columns, it relies on single image much like your solution, only it is typically very wide and very short.
For a percentage width column, imagine you have a 20% column and an 80% body, due to the slightly odd behaviour of percentage background positioning you must produce an image approximately 2000 pixels wide and 1 pixel high. 20% (400 pixels) of the left of that image are your bar. Simply paint them a colour and leave the rest transparent, or vice verca if you want to maintain a white page background and control your bar colour with CSS. This image could be doubled to 4000pixels to cover screen resolutions well into the next millenium.
em positioning is more straightforward, simply produce a 2000 - 4000 pixel wide and 1 pixel high white image and set it 20em left if your column is 20em wide.
If you start using textured columns, which is possible, it might get a little image heavy when using percentage widths. But to texture an em width column you simply set the texture as the page background, place your column in a container, and use an white image set 20em in from the side of that container to clip your textured background to the column width.
1px * X images tend to stay around 1kb.
This has probably been said/done before. But I will post it here anyway.
List formatting
First you need to remove/clear the left padding and margins.
ul{ margin-left:0; padding-left:0; }Now, to indent the list XXpx just add the the number of pixels to either the left padding or left margin.ul{ margin-left:XXpx; padding-left:0; }orul{ margin-left:0; padding-left:XXpx; }Default values
Case-sensitivity in ID syntax
One thing to keep in mind is the Case-sensitivity of ID syntax selectors. If you assign
<div id="Top">blah</div>and declare #top in your style sheet, it won't work. Though I've never heard ANYONE give a good reason for case-sensitivity in any coding language, I've found a use here…I use the case-sensitivity to keep the difference between class and ID straight in my head. Plus, it also stresses the fact that ID syntax selectors combined with a context will override later declared styles. This refutes the normal cascading rule. Take the following example. It will show as blue, even though there are several styles later declared in the style both class and contextual. The syntax-selector-context combination takes precedence. See why
<style type="text/css"> #Top { color:#CC9900; /*orange*/ } #Top i { color:#0033CC; /*blue*/ } .blah p i { color:#669900; /*green*/ } p i { color:#9900CC; /*purple*/ } i { color:#990000; /*red*/ } </style> </head> <body> <div id="Top"> <div class="blah"><p><i>stuff here</i></p></div> </div> </body>As a side note, one of the reasons they're case sensitive is they're used by JavaScript, which happens to be a Case-sensitive language. Another handy feature, IDs can also be used as anchor links!
Because of these last two uses, IDs should never be declared more than once on a single page. So wrap blocks and utilize the cascading as much as possible, but do not assign it repeatedly as you would a class style. It's not like the browser is going to crap out, but standards also say this is bad, and if you're a good little web coder, you're striving for standards.
I'm getting off my original topic, so read this if you're curious about that standard: http://www.w3.org/TR/REC-CSS2/selector.html#id-selectors.
The markup's godawful in this thread
<br />tags in the CSS would make it easier for our less advanced friends to read the code.Markup improved for you
Any better?
Folks, could we please follow the code style guide? Particularly the bits about submitting code samples.
Display:none
Tip number ten
font-variant
about !important
multiple classes on one element
How well supported are multiple classes? Seen any good reviews of potential browser issues?
Note that it's illegal to declare classes separately for one element (class="x" class="y") as opposed to (class="x y").
thanks, m
SEO
Re: SEO
I wouldnt worry about the keyword Density of your stylesheet
Thanks,
Brad Henry
Re: SEO
Specificity
shaded border