lesson 2
CSS part 1
Syntax
Each style rule is made up of one selector and one declaration.
The declaration defines one or more property:value
pairs describing a specific style setting,
and the selector identifies one or more elements to which those settings are to be applied.
selector {
property: value;
}
Shorthand syntax
A handfull of properties can be written in either short- or longhand notation.
font
, background
, margin
, padding
, border
, outline
, list-style
, and transition
all have sub-properties that can be written separately, or combined into a single property:
selector {
background-color: red;
background-image: url('/images/red-tile.png');
background-repeat: repeat;
background-position: 0 0;
}
selector {
background: red url('/images/red-tile.png') repeat 0 0;
}
selector {
margin-top: 5px;
margin-right: 10px;
margin-bottom: 15px;
margin-left: 20px;
}
selector {
margin: 5px 10px 15px 20px; /* top, right, bottom, left */
margin: 5px 10px 15px; /* top, left-right, bottom */
margin: 5px 15px; /* top-bottom, left-right */
margin: 5px; /* top-right-left-bottom */
}
Each property has it's own specific syntax and rules, so keep a reference link handy
Units of measure
CSS supports serveral different units of measure, many of which only make sense when printing. In a screen based context, there are only three suitable measurement units:
- pixels (
px
): the smallest point a screen can physically display (hardware pixel) - ems (
em
): hight of the browser's base text size (usually 16px) - percentage (
%
): the percentage of a reference value (changes based on context)
Ems and percentage are clearly relative units, but because some newer devices have vastly higher pixel densities, the hardware pixel can be considered a relative value as well. Devices like the iPhone 4, with a pixel density of 2, need to render pixel measurements at twice their actual size in order to compensate. There are changes afoot to develop an optical reference pixel that would be the same absolute size across all screens, but we aren't there yet.
Vendor Prefixes
Introduced in CSS 2.1 as a 'beta' flag for new style properties, vendor prefixes allow browser vendors to implement new features before there is a standard syntax. On the whole, this is a good idea, but in practice it can mean more typing:
-webkit-transition: background-color 0.25s;
-moz-transition: background-color 0.25s;
-ms-transition: background-color 0.25s;
-o-transition: background-color 0.25s;
transition: background-color 0.25s;
Most of the new CSS3 features are still vendor prefixed in the latest versions of browsers, so be sure to consult a reference before writting.
Vendor prefixes are good for the web: don't just use -webkit-
and forget the rest
Selectors
A rule's selector can vary from the very specific to the very general, targeting one or many elements at a time. Selector syntax is very flexible, and is designed to allow for combining and grouping individual types.
Basic selectors
Select by id
Select a specific element by id:
#wrapper {
margin: 20px;
}
Select by class
Select one or more elements by class:
.highlight {
color: yellow;
}
Select by tag name
Select one or more elements by tag name:
p {
padding: 0 10px 20px;
}
Select descendants
Select one or more elements nested (at any level) within a parent element:
li a {
text-decoration: underline;
}
Select direct descendants
Select one or more elements nested directly below a parent element:
#wrapper>section {
float: left;
}
Select by attribute
Select one or more elements based on their attributes:
/* all img elements with a title attribute */
img[title] {
border: 1px solid red;
}
/* all a elements with a specific link destination */
a[href="#"] {
background-color: #3c3c3c;
}
/* all a elements starting with a specific value (external links) */
a[href^="http"] {
background-image: url('images/external-link.png');
}
/* all form submit buttons */
input[type=submit] {
border: none;
}
Select by pseudo class
Select one or more elements based on a specific state:
/* all a elements during mouse hover state */
a:hover {
text-decoration: underline;
}
/* all input textfield elements during keyboard focus */
input[type=text]:focus {
color: red;
}
/* all divs except for #wrapper */
/* NOT FOR OLDie */
div:not(#wrapper) {
margin: 2em
}
Select a pseudo element
Select one or more parts of an element:
/* first line of all paragraphs */
p::first-line {
padding-left: 10px;
}
/* first letter of all paragraphs */
p::first-letter {
font-size: 1.2em;
}
Pseudo elements are designated by double :: but work with single : for backwards compatibility
Selector Collections
Selectors can be collected in order to apply a style declaration to many elements at the same time:
/* HTML5 reset */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
/* typographic styles common to all headings */
h1, h2, h3, h4, h5 {
font-family: "Gill Sans", sans-serif;
letter-spacing: 1px;
}
Selector parsing
Knowing how browsers parse selectors helps avoid inefficient element selection and potential performance issues. The right-most selector in a selector combination is referred to as the key selector because selectors are matched from right to left. This enables browsers to determine which elements don't match as quickly as possible.
Selectors with a right-most selector that matches many elements can have an impact on page rendering speed
Inheritance
Certain style properties are inheritable, passed down from parent to child through the DOM tree.
This allows child elements to automatically adopt styles without any explicit declaration.
The most important inherited styles are typographic
(color
, font-size
, font-weight
, font-family
, line-height
, text-align
, etc):
body {
font-size: 14px;
font-family: sans-serif;
color: black;
}
Define your basic typographic rules on the body
in order to force a consistent style
The Cascade
The cascade is a set of rules that determine which styles are ultimately applied to an element when there are multiple sources, including which styles prevail during conflict. If more than one style is applied from different rules, they are combined, and any conflicts are resolved based on the rule's specificity.
Specificity
When there are conflicting styles, properties of the most specific style overwrite less specific ones. Browsers use a formula to determine a style's specificity based on values assigned to the style's selector:
- Automatic User Agent styles are worth the least
- Tag and generic selectors are worth more than the built in browser styles
- Class selectors are worth more than tags
- ID selectors are worth more than classes
- Inline styles written in the element
style
attribute are worth the most
UA styles < tag < class < id < style attr
In the case of a tie, the last style to be applied wins.
!important
Because of this value based approach, there are some cases where it may be very difficult to override a particular style, particularly when ID selectors have been used. In these cases, it is possible to overrule any style no matter it's specificity:
#nav a {
color: red;
}
a {
color: black !important;
}
Avoid the use of !important
under all but the most life-threatening circumstances
Resets
Because browsers apply default styling to most elements (especially form
elements), it can be desirable to reset styles to a basic state before you begin any styling.
As mentioned in the previous lesson, it's sometimes also necessary to apply display:block
to HTML5 structural elements.
These reset rules should be included before all others to ensure that they don't overrule any custom style declarations.
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
Resets even out browser rendering differences by resetting their default styles
The Box Model
Though probably obvious, it's important to note that every element rendered by the browser is bound by a rectangular box. This box, and the properties that make up it's dimensions, is known as the box model. The model affects the dimensions of elements and how they interact with each other.

- content area: the space needed to render the content
- padding: the inside space between the content and the content's border (shared background)
- border: the coloured stroke applied to the outside of the element
- margin: the outside space between the element and it's neighbours (transparent)
By default, the actual dimension of an element, and the space it takes up on screen, includes the padding and border dimensions.
Although perhaps not entirely logical, the width
and height
properties define the content width and height only, not it's bounding rectangle.
Width = width
+ padding-left
+ padding-right
+ border-left
+ border-right
This behaviour has implications for defining precise pixel dimensions of elements, as well as relative, percentage based layout:
/* actual box dimensions are 540px X 240px */
#box {
width: 500px;
height: 200px;
padding: 20px;
}
/* actual column width is wider than 50% */
.column {
width: 50%;
height: 100%;
padding: 0 20px;
}
Remember that the default behaviour for block-level elements is to take up all available width,
so it's often desirable to set width:auto
instead of width:100%
.
This will allow the use of padding and borders where otherwise it would not be possible.
More here
This default behaviour can often be frustrating, and will sometimes lead to extra markup to fix layout problems. One option, however, is to change the box model behaviour to include padding and border dimensions inside width/height declarations:
.sane-box-model {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
/* actual width will be 100% and will play nice with the neighbours */
div.sane-box-model {
width: 100%;
padding: 40px;
border: 10px solid red;
}
This property is supported on all browsers since IE8, so it's generally safe, and even recommended by some to apply to all elements:
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
Display
Before we embark on questions of layout and positioning, it's useful to first address the various display states available to elements.
The aptly named display
property is the most important way to control an element's rendering:
none
: element display is disabled, including nested children, as though the element did not existinline
: element behaves like an inline-level HTML elementblock
: element behaves like a block-level HTML elementinline-block
: element behaves like a block-level element but flows with surrounding content (can have margins, height, etc)table
: element behaves like atable
HTML elementadditional table related
: there are further states that correspond to table specific child element behaviour (table-row
,table-cell
, etc)
Visibility
Another means of controlling the display of an element is with the visiblity
property. Unlike display
, visiblity
does not alter the document flow,
but simply changes whether the element is visible or not:
hidden
: element is invisible, but document layout is still affected by it's size and positionvisible
: element is fully visible
Opacity
Conceptually related to visibility
, the opacity
property controls the degree of transparency of an element:
<img src="/images/image.jpg">
img {
opacity: 0.25;
}

OldIE doesn't support the opacity
property, but you can achieve the same with the IE-only
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
[Note that opacity values are from 0-1, and IE filter from 0-100]
Overflow
When the content inside an element is larger than it's defined width
and height
,
the content can spill outside of it's container in all sorts of odd ways. By specifying an overflow
property, you can control the behaviour:
visible
: content is not clipped and may render outside the content box (default)hidden
: content is clippedscroll
: content is clipped and scrollbars are added whether they are needed or notauto
: content is clipped and scrollbars are added if needed
Positioning
Controlling the position of elements is one of the most important, and often challenging, tasks of the styling process.
The primary tool for directing the position of elements is the position
property:
static
: normal position in the flow of the document (default)relative
: normal position in the flow of the document, plus optional offsets (top
,bottom
,left
,right
). Also used to establish a new coordinate space for child elementsabsolute
: outside of normal document flow, and positioned relative to it's nearest positioned ancestor using optional offsetsfixed
: outside of normal document flow, and positioned relative to the viewport using optional offsets (does not scroll)
<div id="#wrapper">
<div id="#box1" class="box"></div>
<div id="#box2" class="box"></div>
</div>
#wrapper {
position: relative;
}
.box {
width: 40px;
height: 40px;
background-color: #f26522;
}
#box1 {
position: absolute;
bottom: 10px;
right: 10px;
background-color: #009BC8;
}
Centering
Trying to center an element, either vertically or horizontally, is often more frustrating than you would expect it to be. Certainly, centering horizontally is far easier than the vertical variety, and in all cases it's far easier with elements that have a fixed dimension.
Margin auto
Using margin value of auto
for both margin-left
and margin-right
will center a block element:
<div id="#box1"></div>
#box1 {
width: 40px;
height: 40px;
background-color: #f26522;
margin: 0 auto;
}
Negative margins
Positioning an element absolutely in the middle of it's parent, then applying negative margins equal to half it's height and width will center a fixed sized block element:
<div id="#wrapper">
<div id="#box1"></div>
</div>
#wrapper {
position: relative;
}
#box1 {
position: absolute;
top: 50%;
left: 50%;
width: 40px;
height: 40px;
margin-top: -20px;
margin-left: -20px;
background-color: #f26522;
}
Text-align center
Adding text-align:center
to a parent container will horizontally center all inline elements (text, images, etc):
<div id="#wrapper">
<p>text</p>
<img src="/images/little-image.jpg">
</div>
#wrapper {
text-align: center;
}
text

Line-height
Adding line-height
equal to height
will center a single line of text vertically:
<li>
<a>menu link</a>
</li>
li {
background-color: #666666;
}
li a {
height: 100px;
line-height: 100px;
}
MENU LINK
This is just scratching the surface of all the hacky posibilities that lay just one Google search away.
Taming the layout beast will require patience and experimentation
Floating
The float
property is another way to control layout, allowing an element to pull right or left and have content flow around itself.
This is often used to wrap text around images, but can also be used to create column layouts and horizontal menus. The values for float
include:
left
: element floats on the left side of its containing blockright
: element floats on the right side of its containing blocknone
: element does not float
Here is the intended use of floats:
<div id="#wrapper">
<p>I love cats, they are so cute and cuddly and they smell nice.</p>
<img src="/images/little-image.jpg">
</div>
img {
float: left;
}

I love cats, they are so cute and cuddly and they smell nice.
And an example of using it for structural layout:
<div id="#wrapper">
<div id="#box1" class="box"></div>
<div id="#box2" class="box"></div>
</div>
.box {
width: 40px;
height: 40px;
}
#box1 {
float: left;
background-color: #f26522;
}
#box2 {
float: right;
background-color: #009BC8;
}
Clearing
Because floating elements takes them out of the regular flow of the document, we often get undesirable behaviour with content that comes after those elements.
The clear
property is the companion to float
in that it determines how non-floated siblings react to a floated brother or sister:
none
: element does not move out of the way of floated contentleft
: element moves down to clear past left floatsright
: element moves down to clear past right floatsboth
: element moves down to clear past both left and right floats
<div id="#wrapper">
<div id="#box1" class="box"></div>
<div id="#box2" class="box"></div>
<div id="#box3"></div>
</div>
.box {
width: 40px;
height: 60px;
}
#box1 {
float: left;
background-color: #f26522;
}
#box2 {
float: right;
background-color: #009BC8;
}
#box3 {
clear: both;
width: 100%;
height: 20px;
color: #00c830;
}
Collapsing
A side-effect of all this floating is that a container of floated elements will collapse on itself unless it has a defined height
(floated elements are taken out of the regular flow, remember?). There are many ways to 'fix' float clearing to prevent collapsing,
including adding a bottom element with clear:both
as in the above example.
If we wish to avoid extra markup, we can use one of the following tricks:
/* this will trick the container into not collapsing... */
/* ...but may hide content */
#wrapper {
width: 100%;
overflow: hidden;
}
/* this is the same as adding an extra element in markup, but all in css */
#wrapper:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
z-index
With the ability to position elements nearly at will, it often becomes necessary to manage element stacking order.
Controlling the order in which elements overlap is done with the z-index
property,
which simply takes a numeric value (negative or positive) to resolve which element lies above another:
<div id="#wrapper">
<div id="#box1" class="box"></div>
<div id="#container">
<div id="#box2" class="box"></div>
<div id="#box3" class="box"></div>
</div>
</div>
#wrapper {
position: relative;
}
.box {
position: absolute;
width: 40px;
height: 40px;
}
#box1 {
top: 10px;
left: 10px;
z-index: 3;
background-color: #f26522;
}
#box2 {
top: 30px;
left: 30px;
background-color: #009BC8;
z-index: 2;
}
#box3 {
top: 50px;
left: 50px;
background-color: #00c830;
z-index: 1;
}
z-index
only works on positioned elements (relative
, absolute
, or fixed
)
Stacking order is also subject to the current stacking context, much like positioning is subject to positioning context. So, if a group of stacked elements reside in a stacked parent, their stacking order is relative to each other, not the global stacking order:
<div id="#wrapper">
<div id="#box1" class="box"></div>
<div id="#box2" class="box"></div>
<div id="#box3" class="box"></div>
</div>
#wrapper {
position: relative;
}
.box, #container {
position: absolute;
}
#box1 {
z-index: 3;
background-color: #f26522;
}
#container {
z-index: 2;
background-color: #cccccc;
}
#box2 {
background-color: #009BC8;
z-index: 999;
}
#box3 {
background-color: #00c830;
z-index: 100;
}
the default value for z-index
is 0
, so negative values will position an element behind non-positioned/stacked elements