Default Styles

Here's a page of unstyled HTML right? Wrong! It is impossible to display the content on that page without making some style decisions somewhere (e.g. what font should be used to render the text). Additionally, various headings have different font sizes, links are blue and underlined and elements have some amount of margin and padding. Yet none of these styles are defined inline, within a style element or in an external stylesheet. So where are they coming from?

The answer is that every browser (sometimes referred to as "user agent") has its own default stylesheet, for displaying HTML elements. In fact you can see here the default stylesheets for Firefox and Webkit (the rendering engine for Safari and Chrome among others).

The only problem with this is that there is no standard telling browsers the "correct" way to render elements by default, so, while similar, different browsers' default stylesheets are inconsistent with each other. You might get a site looking perfect in one browser and find it looks wrong on another browser because a default style you relied on in browser A is different in browser B. This is most often evident with margins and padding.

To avoid this, you can use a "CSS Reset" or "CSS Normalizer" like normalize.css


CSS Specifity

It is possible (and quite common) to redefine styles in such a way that there is more than one style definition for a give HTML element.

Take this example. I want Item 2 to be styled red and bold. It is rendering the bold font-weight, but not the red coloured text. This is because the color: black style, which also targets Item 2 is in a more specific selector - #myList li

The rules for which of multiple conflicting styles should be applied may seem convoluted, but are necessarily defined. This article does a good job of explaining them.

The best way of avoiding confusing CSS specificity issues is to only make your CSS rules as minimally specific as needed.


Inline vs block-level elements

Block Level elements

A div is a block level element, it will take up all of the horizontal space available to it (by its parent element).

Examples of Block Elements:
<p>, <div>, <form>, <header>, <nav>, <ul>, <li>, and <h1>.

This still applies even if we explicitly set the width of a block element...

width: 50%
width: 30%

Inline elements

A span is an inline element, it takes up only as much horizontal space as it needs

Inline elements flow with text. This is a span (which is an inline element) inside of a paragraph (which itself is a block element)

Examples of Inline Elements:
<a>, <span>, <b>, <em>, <i>, <cite>, <mark>, and <code>.

You can override the default block/inline behaviour of any element using the CSS display property.

For example, take the following list

List items (<li>) are, by default a block level element (therefore they take up all the horizontal space available to them). We can change this into a horizontal list, by changing the display property of the list items to inline like so:

.horizontalList li { display: inline; }

Read more about inline vs block elements here: http://www.impressivewebs.com/difference-block-inline-css/

inline-block

Inline elements will ignore the width and height properties. If you want an element to otherwise display inline, but respect the height and width properties, you can use display: inline-block

Example: here's our horizontal list again. Both have their li styled with width: 100px. The first list ignores the width property because it is set to display: inline. The second list is set to display: inline-block, which respects the width style.


Floats

Floating elements causes their parent container to collapse:

float: left
float: right

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet animi doloremque earum, eveniet incidunt ipsa quam quidem. Deleniti eos et facilis id, ipsam similique sit vero? Aliquid asperiores dolor veritatis?

WTF!? this heading shouldn't be here! It should sit below the floated content!

What's the best way of clearing floats?

There are several methods to clearing floats, but the "best" way currently is to use a "clearfix" class. Create a class that looks like this, then apply it to any container element that has floated content:

.clearfix:after { content: ""; visibility: hidden; display: block; height: 0; clear: both; }
float: left
float: right

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet animi doloremque earum, eveniet incidunt ipsa quam quidem. Deleniti eos et facilis id, ipsam similique sit vero? Aliquid asperiores dolor veritatis?

Ahh, that's better

Read more about floats here: http://css-tricks.com/all-about-floats/


Margins, padding and how the dimensions of an element are calculated (CSS Box Model)

width: 200px;
height: 100px;
margin: 1em;
padding: 1em;
width: 200px;
height: 100px;
margin: 1em;
padding: 0;

Both these divs have their width set to 200px and their height set to 100px, yet they are clearly different sizes. This is because when calculating the actual amount of space an element will take up you need to add on the padding, border and margin.

You can change this behaviour by using changing the box-sizing style from its default value (content-box) to border-box. Here's the same two divs again. The only difference is they have the style: box-sizing: border-box

width: 200px;
height: 100px;
margin: 1em;
padding: 1em;
width: 200px;
height: 100px;
margin: 1em;
padding: 0;

Read more about the box-sizing display property and examples where you might want to use it here: https://css-tricks.com/box-sizing/

Read more about the CSS Box Model here http://css-tricks.com/the-css-box-model/


Positioning

The default positioning for all elements is position:static, which means the element is not positioned and occurs where it normally would in the document layout.

There are other values for the position property that are useful for positioning content differently to how it would normally appear:

position: relative

If you specify position:relative, then you can use the top or bottom, and left or right css properties to move the element relative to where it would normally occur in the document.

position: absolute

If you specify position:absolute, then the element is positioned relative to it's closest parent with position: relative. If there is no ancestor with position: relative the absolutely positioned element is positioned relative to the browser window.

position:relative + position:absolute

Using a combination of position: relative on a container element and position: absolute on its child elements is a very powerful way of positioning the child element within its parent container

container ==> position: relative
position: absolute;
top: 0;
left: 0;
position: absolute;
top: 0;
right: 0;
position: absolute;
bottom: 0;
left: 0;
position: absolute;
bottom: 0;
right: 0;
position: absolute;
top: 33.33%;
left: 33.33%;
position: absolute;
top: 0;
left: 33.33%;
position: absolute;
bottom: 0;
left: 33.33%;
position: absolute;
top: 33.33%;
right: 0;
position: absolute;
top: 33.33%;
left: 0;

Read more about CSS positioning here: http://www.barelyfitz.com/screencast/html-training/css/positioning/

Great article on how to center anything with CSS

Article on (responsive) absolute horizontal and vertical centering.


z-index

The z-index property specifies the stack order of an element. Elements with a higher z-index appear in front of elements with a lower (or undefined) z-index.

z-index only works on positioned elements (position:absolute, position:relative, or position:fixed).

Read more about the intricacies of z-indices here.


Finally, this site provides an excellent explanation of CSS Layout with great visual examples.