Pivotal Labs Dev Center
Getting Started
Process & Flow
General Tips & Tricks
Strategies & Solutions
Why do we care if the CSS is well-written? For the same reasons why we like good code:
Here are some guidelines that help you write good markup
<h1><a>Text</a></h1> <!-- VALID --!>
<a><h1>Text</h1></a> <!-- NOT VALID --!>
Using XHTML is recommended over HTML because XHTML is valid XML, and can be parsed by browsers, XSLT, etc.
As referenced from W3Schools
Strict or Transitional?
The more you add ids and classes, the more complexity you are injecting into the system. Creating more potential for useless or confusing css code.
When do we use classes? Classes are great for denoting important parent nodes in the DOM (body), or describing contents of tags (users). IE6 has some issues with multiple classes (more on that later)
Naming conventions: Check this naming conventions table, which shows what popular sites are using for their markup names.
CSS shorthand is more compact and can make your code easier to scan quickly, when maintaining your code. Here's a link to shorthand properties
margin: x y; /* top/bottom left/right */
margin: x y z; /* top left/right bottom */
margin: w x y z; /* top left right bottom */
border: width style color;
background: color image repeat attachment position;
/* verbose */
background-color: #f00;
background-image: url(background.gif);
background-repeat: no-repeat;
background-attachment: fixed;
background-position: 0 0;
/* compact (order can matter in old versions of safari) */
background: #f00 url(background.gif) no-repeat fixed 0 0;
/* verbose */
font-style:italic;
font-variant:small-caps;
font-weight:bold;
font-size:1em;
line-height:140%;
font-family:"Lucida Grande",sans-serif;
/* compact */
font:italic small-caps bold 1em/140% "Lucida Grande",sans-serif;
The idea behind content-driven CSS design is to use an iterative development process that emphasizes creating semantically accurate markup, while maintaining consideration for other factors that will determine the your implementation strategy.
Developing your CSS iteratively helps you keep your code simple, designing only as needed.
What's the simplest thing you can do to make it work? Design the markup as semantically and simply as possible. This will not only aid in search engine optimization, but also lends itself to be more easily interpretable and editable. This also forces you to determine up front what the content will be if no mockup exists for the feature you're working on.
Whether you are trying to decide how to implement your site's overall layout from your mockups, coming up with your site's rounded corners strategy or styling page-specific content, its always good to have a plan of attack before going head-first into the code.
The nature of CSS allows for many different solutions to solve the same problem, for better or worse. In the latter case, its important to understand the advantages and disadvantages of each technique you choose.
Understand your constraints. Using rounded corners as an example, do you need to support gradients in your rounded corners? Can the background behind your rounded corner container be different colors? Do you need to have borders and drop shadows?
In our Strategies & Solutions section, we try to help guide you towards finding the appropriate implementation technique for common CSS challenges by describing advantages and disadvantages of each.
CSS selectors and pseudo-elements are very handy tools to streamline both your markup and your CSS. Its possible to get by without using them, but they can make life so much easier.
IE Compatibility. Not all selectors and pseudo-elements are supported by IE 6/7, but there is at least one javascript extensions that give IE the capability to use them. IE7-JS supports not only selectors/pseudo-elements, but also supports provides IE the ability to utilize other functionalities such as PNG support.
Especially useful selectors: >, *, +, E[ ]
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
ul li:before {
content: ' | ';
}
ul li:first-child:before {
content: ' ';
}
My rule of thumb is, if I set a width, I don't set margin or padding. Likewise, if I'm setting a margin or padding, I don't set a width. Dealing with the box model can be such a pain, especially if you're dealing with percentages. Therefore, I set the width on the containers and then set margin and padding on the elements within them. Everything usually turns out swimmingly.Jonathan Snook
If you set a width, you should probably avoid setting padding on that same item, as padding increases the width of the specified container. Instead, add a child element and specify it as padding on that element. It does add markup to your page, but it can greatly improve flexibility and control working within the box model.
See the code below this example for more details.
Example 1: Baseline box with 50% width, and no padding.
<div id="box">
50% width, no padding.
</div>
#box {
width: 50%;
}
Example 2 (our preferred method): Baseline box with 50% width, and no padding.
<div id="box">
Box 50% width, with an inner child element giving us the padding we want (15px in this case)
</div>
#box {
width: 50%;
}
#box > span.inner {
padding: 15px;
}
Example 3 (typical implementation): Baseline box with 50% width and padding applied to it. Notice that even though you gave it a width of 50%, the actual width is larger than 50% because of the padding. Not idea. There's no point in giving it a 50% width if it isn't going to actually be 50%. Notice that in this scenario, even our fixed height of 100px is no longer true. The padding has increased the height to 130px.
<div id="box">
Box with 50% width and padding: 15px applied to it.
</div>
#box {
width: 50%;
padding: 15px;
}
This is an essential technique that can be applied to different CSS strategies including tooltips, vertical centering and equal-height columns. The essence to this technique is that, when you have a relatively-positioned parent element, you can take the child element out of flow and position it relative to the parent's box.
<div class="nested_positioning_example">
<div class="abs">Absolutely Positioned Div</div>
</div>
.nested_positioning_example {
position: relative;
}
.abs {
position: absolute;
top: 20%;
left: 90%;
}
Three popular ways to vertically center are using
Markup to vertically center
<div id="vertically_center_example">
<span>Center me!</span>
</div>
Set the line-height to be the same as the height of the container.
Advantages: Very simple to use.
Disadvantages: This only works if you only have 1 line of text to center, and you know the height of its container.
#vertically_center_example {
height: 5em;
line-height: 5em;
}
The vertically positioned element needs to be position: absolute, 50% from the top of its parent container with a negative margin of half its height.
Advantages: Works for any type of element, including multiple lines of text.
Disadvantages: This only works if you know the element you want centered has a fixed height.
#vertically_center_example2 {
position: relative;
}
#vertically_center_example2 span {
display: block;
position: absolute;
height: 1em;
top: 50%;
left: 0;
margin-top: -0.5em;
}
Doesn't work in IE 6/7/8 (at least not yet for IE8).
Here are a couple popular ways to style adjacent columns so they share the same height, which is determined by the size of content in the main div.
24 Ways introduced this method they call Absolute Columns to solve this common problem.
Advantages: This method is very simple to implement and understand. It is very easy to adjust column properties, such as color and width.
Disadvantages: You have to know which column will have the greater amount of content. In most cases this is the case, so its generally not an issue. To make it work perfectly in IE, you may need to add an additional line of CSS.
The idea that drives this technique is that
Our Absolute Columns Live Demo example
<div id="container">
<div id="column-left">
<h2>#left</h2>
</div>
<div id="column-mid">
<h2>#mid</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
</div>
<div id="column-right">
<h2>#right</h2>
</div>
</div>
#container {
position: relative;
background-color: #DDD;
}
#column-left {
width: 80%;
background-color: #990000;
}
#column-right {
position: absolute;
top: 10px;
right: 0px;
bottom: 10px;
width: 20%;
overflow: auto;
}
A List Apart describes another method known as Faux Columns, aptly named because the method gives the appearance of equal-height columns despite the fact, each column container is only as tall in height as its content.
Advantages: This method is also very simple to implement and understand.
Disadvantages: Fixed width solution only. Requires a background image to provide the colors of each column. It is also not very flexible, as any changes to the width and color of any column requires a new image be created.
The idea that drives this technique
Our Faux Columns Live Demo example
<div id="container">
<div id="column-left">
<h2>#left</h2>
</div>
<div id="column-mid">
<h2>#mid</h2>
</div>
<div id="column-right">
<h2>#right</h2>
</div>
</div>
#container {
width: 800px;
overflow: hidden;
background: url(/images/faux_columns/bg.png) repeat-y top left;
}
#column-left {
float: left;
width: 160px;
}
#column-mid {
float: left;
width: 480px;
}
#column-right {
float: right;
width: 160px;
}
This is a common technique using CSS to create a footer that sticks to the bottom of the window or page content, when you don't have enough content to fill your browser window. Read more about sticky footers
Advantages: Works in all browsers and is relatively simple to implement for most layouts.
Disadvantages: This technique is hard to work with if you are mixing 100% width layout elements and fixed width layout elements, but not unworkable.
The idea that drives this technique is that
Our simple sticky footer example
<div class="wrapper">
<div class="push"></div>
</div>
<div class="footer">
<span>I'm the sticky footer</span>
</div>
html, body {
height: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -5em;
}
.footer, .push {
height: 5em;
}
There are 48392743289 different ways to do rounded corners, but there's no one perfect method.
Here are some examples
Use browser-specific CSS.
Advantages: Very simple to use.
Disadvantages: Does not work in IE and is not anti-aliased.
-moz-border-radius: 0.2em;
-webkit-border-radius: 0.2em;
A simple method that requires an image for each corner (or a single image through CSS Sprites). Transparency is optional, but if you have transparency you can make the inside portion of the rounded corner images transparent, which allows you to change the background color of the rounded element via CSS. Additionally, this method supports font-scaling in all browsers, as rounded images stay at the corners of the rounded container in all situations.
Advantages: Simple CSS, works gracefully with font-scaling. Very easy to modify corners you want rounded.
Disadvantages: Additional markup is required.
The idea that drives this technique is that
<div class="absolute_rounded_corners_example example">
<div class="tl"></div>
<div class="tr"></div>
<div class="bl"></div>
<div class="br"></div>
</div>
.absolute_rounded_corners_example {
position: relative;
height: 6em;
width: 15em;
margin: 2em;
background-color: #004400;
}
.tl, .tr, .bl, .br {
position: absolute;
height: 10px; width: 10px;
background-image: url(/images/absolute_roundies.png);
background-repeat: no-repeat;
}
.tl {
top: 0; left: 0;
background-position: top left;
}
.tr {
top: 0; right: 0;
background-position: top right;
}
.bl {
bottom: 0; left: 0;
background-position: bottom left;
}
.br {
bottom: 0; right: 0;
background-position: bottom right;
}
The sliding doors technique involves using two adjacent markup elements to create the rounded corner aesthetic. In our example, we will use a list tag and an anchor tag. These two adjacent elements display the left and right sides of the rounded corner container, with one side expanding horizontally in a "sliding door" fashion, based on the length of the content within it.
Advantages: Potentially no additionally markup required. Works with vertical gradients.
Disadvantages: Images are required. Basic implementation does not font-scale. Does not support transparency behind the container.
The idea that drives this technique is that
<div class="example_container">
<ul class="sliding_doors_example">
<li><a href="#rounded_corners" name="">Tab 1</a></li>
<li><a href="#rounded_corners" name="">Tab Two</a></li>
<li><a href="#rounded_corners" name="">Another Tab</a></li>
</ul>
</div>
ul.sliding_doors_example {
overflow: hidden;
}
ul.sliding_doors_example li {
list-style-type: none;
float: left;
margin-right: 0.3em;
width: auto;
padding-left: 25px;
background: url(/images/sliding_doors.png) no-repeat top left;
}
ul.sliding_doors_example li a {
display: block;
padding: 10px 25px 10px 0;
background: url(/images/sliding_doors.png) no-repeat top right;
}
Use javascript to add necessary DOM elements, can be image or non-image based.
Advantages: Many different solutions already available. Template markup is cleaner.
Disadvantages: Usually inserts many DOM nodes, different solutions have varying support for the visual effect you are trying to achieve.
Make font-size ~= 10px
font-size: 62.5%;
Image replacement
h1 {
text-indent: -9999em;
width: 182px;
height: 28px;
background: url(../images/overview.png) no-repeat top left;
}
<h1>Image replacement</h1>
Forcing anchors not to wrap
a {
white-space:nowrap;
}
Removing active anchor outlines
a:active, a:focus {
outline:none;
-moz-outline: none; /* for firefox */
}
Fixing rails form error indicators
form .fieldWithErrors {
display: inline;
}
CSS3 is still going through a lot of changes. Read up more on its future