CSS
Table of Contents
CSS Selectors
Basic Selectors
- Type selector: Select elements by their type. Ex:
a,p,divwill select all elements of typea,panddivrespectively - Id selector: Select elements by their id. Ex:
#john-doewill select any element with idjohn-doe,div#john-doewill select adivelement with#jonh-doeid - Descendant selector: Select an element inside another element. Ex:
p strongwill select allstrongelements inside apelement,ul li#john-doewill select theli#john-doeelement within aulelement,ul#people liwill select alllielements within aul#peopleelement. - Class selector: Select elements with a given class. Ex:
li.spanishwill select alllielements with.spanishclass,.spanishwill select all elements with.spanishclass - Univeral selector: Selects every element. Ex:
*selects every element,ul *selects every element inside aul
You can also combine selectors by separating them with ,, that way you can apply the same styling rules to groups of elements. For instance:
li.warning,
li.special,
li.important {
font-weight: bold;
}
Advanced Selectors
Attribute selectors
The attribute selectors allow you to select elements that have a specific attribute or a specific value for an attribute. The attribute selectors are quite flexible:
- Select an paragraph with an attribute
class: p[class] - Select an paragraph whose
classattribute value is equal tonews: E[class=“news”] - Select an paragraph whose
classattribute value is a list of whitespace separated values and one of which isnews: E[class~=“news”] - Select an paragraph whose
classattribute value begins withbar: E[class^=“news”] - Select an paragraph whose
classattribute value ends withbar: E[class$=“news”] - Select an paragraph whose
classattribute value contains the substringbar: E[class*=“news”] - Select an paragraph whose
classattribute value is a list of hyphen separated values beginning withbar: E[class|=“news”]
Adjacent sibling selector
Selects an element that directly follows another element. Elements that follow one another are called siblings. They are on the same level of depth, so when I say that an element follows another element directly I mean at the same level of depth within the DOM tree.
plate + apple {
/* css */
}<table>
<plate><apple/></plate>
<plate></plate>
<apple/> <!-- SELECTED -->
<plate><orange></plate>
<apple/> <!-- SELECTED -->
<apple/>
</table>General sibling selector
As above but this time it selects an element that follows another element (it doesn’t have to be immediately after).
plate ~ apple {
/* css */
}<table>
<plate><apple/></plate>
<plate></plate>
<apple/> <!-- SELECTED -->
<plate><orange></plate>
<apple/> <!-- SELECTED -->
<apple/> <!-- ALSO SELECTED -->
</table>Child selector
Selects a direct children of another element, a direct children is the first level (direct) descendant.
/* select an apple directly on the table */
table > apple {
/* css */
}<table>
<apple/> <!-- SELECTED -->
<plate><apple/></plate>
<plate><apple/></plate>
<apple/> <!-- SELECTED -->
<plate><orange></plate>
</table>Pseudo-class and Pseudo-elemnet Selectors
This type of selectors allow providing styling based on information that lies outside of the document tree or that cannot be expressed using the other simple selectors, for instance, whether an a element has been visited or has the mouse pointer hovering over, or whether al element is the first child of another element.
Pseudo-classes are allowed anywhere in selectors while pseudo-elements may only be appended after the last simple selector of the selector.
Pseudo-class Selectors
:first-child and :last-child
:first-child selects the first element inside another element. :last-child selects the last element inside another element. Ex: p:first-child selects all first child p elements, that is all first elements that are also a p element:
/* select the first element in a plate if it is an apple */
plate apple:first-child {
/* css */
}<table>
<apple/>
<plate>
<apple/> <!-- SELECTED -->
<orange/>
</plate>
<apple/>
<plate>
<orange/>
<apple/>
</plate>
</table>:only-child
Selects an element that is the only element inside another one:
/* select an apple when it is the only thing on a plate */
plate apple:only-child {
/* css */
}<table>
<apple/>
<plate>
<apple/> <!-- SELECTED -->
</plate>
<apple/>
<plate>
<orange/>
<apple/>
</plate>
</table>:nth-child selector and :nth-last-child
The nth-child(n) selector selects an element by its order in another element. nth-last-child(n) does the same thing but starting the count from the back. Ex: p:nth-child(2) selects a p that is the second child of an element (both conditions must occur i.e. the second child of an element must be a paragraph).
/* select the second thing on the table if it is a plate */
table plate:nth-child(2) {
/* css */
}
/* select the third thing on the table from the back if it is a plate */
table plate:nth-last-child(3) {
/* css */
}<table>
<plate/>
<plate> <!-- SELECTED --> <!-- SELECTED -->
<apple/>
</plate>
<apple/>
<plate> <orange/> </plate>
</table>:first-of-type and :last-of-type
:first-of-type selects the first element of a specific type. :last-of-type selects the last element of a specific type. Ex: ul a:first-of-type selects the first a element within a ul element, a:first-of-type selects the first a element.
/* select the first apple on the table */
table apple:first-of-type {
/* css */
}<table>
<plate/>
<plate>
<apple/> <!-- SELECTED -->
</plate>
<apple/>
<plate><orange/></plate>
</table>:nth-of-type(n)
Selects a specific element based on its type and order in another element. You can also use the special odd or event selectors as a value for n to select elements in odd and even positions. Ex: article p:nth-of-type(2) selects the second paragraph within a article element, but this time, as opposed to the :nth-child selector it doesn’t necessarily have to be the second child.
/* select the second apple on the table */
table apple:nth-of-type(2) {
/* css */
}<table>
<plate/>
<plate>
<apple/>
</plate>
<apple/> <!-- SELECTED -->
<plate><orange/></plate>
</table>Additionally, you can use a more complex formula to select elemnets through :nth-of-type. You can use 3n+2 to select every third element after the second element.
:only-of-type
Selects an element if it is the only one of its type. Ex: ul li:only-of-type selects an li element only if it is the single li inside a ul element.
/* select an apple if it is the only apple in a plate */
plate apple:only-of-type {
/* css */
}<table>
<plate/>
<plate>
<apple/> <!-- SELECTED -->
<orange/>
</plate>
<apple/>
<plate>
<apple/>
<apple/>
</plate>
</table>:empty
Selects elements that don’t have any children.
/* select plates that are empty */
plate:empty {
/* css */
}<table>
<plate/> <!-- SELECTED -->
<plate>
<apple/>
<orange/>
</plate>
<apple/>
<plate>
<apple/>
<apple/>
</plate>
</table>Negation pseudo class
The negation pseudo class :not selects all elements that do not match the negation selector. Ex: article p:not(:first-of-type) selects all p elements but the first one within an article. article:not(.news) selects all article elements that don’t have the class news.
Pseudo-element Selectors
Pseudo-element selectors create abstractions about the document tree beyond those specified by the document language. Pseudo-elements provide authors with the means to style elements such as the first letter or first line of an elements’ content. These are:
::first-line: selects the contents of the first line of an element. Exp::first-lineselects the first line of apelement. It doesn’t match a real element, it matches a pseudo-element that conforming user agents will insert at the beginning of every p element.::first-letter: selects the first letter of an element, if it is not preceded by any other content (such as images or inline tables) on its line.::beforeand::after: they can be used to describe generated content before or after an element’s own content. Ex:li::before { content: '-'}adds-before the content of anylielement.
jQuery Special Selectors
jQuery offers a lot of cool extensions to CSS3 selectors to help you select DOM elements. Some these are:
:animated: select all elements being animated[name!="value"]: select all elements that don’t have this attribute, or do have the attribute with anothervalue:button: select all button elements or elements with[type="button"].:checkbox: select all elements of type checkbox:eq(n): select all elements at indexnwithin the matched set:even(): select even elements, zero-indexed:odd(): select odd elements, zero-indexed:file(): select all elements of type file:first(): select the first matched element:gt(n): select all elements at an index greater thatnwithin the matched set:has(): selects elements which contain at least one element that matches the specified selector:header: selects all elements that are headers, likeh1,h2, and so on:hidden: selects all elements that are hidden. Hidden elements either havedisplay:0, ortype="hidden", or width and height set explicitly to 0, or have an ancestor element that is hidden and therefore they are not shown in the page:image: selects all elements of type image:input: selects all input, textarea, select and button elements:last: selects the last element within a matched set:lt(n): selects all elements at an index lower than indexnwithin the matched set:parent: selects all elements that have at least one child node (either element or text):password: select all elements of type password:radio: select all elements of type radi:reset: select all elements of type reset:selected: select all elements that are selected (for option elements):submit: select all elements of type submit:text: select all input elements of type text:visible: slect all elements that are visible (elements that consume space in the document, that is,opacity: 0andvisibility:hiddenare considered visible)
Other Selectors
For other selectors visit the W3C CSS3 selectors standard.
Using CSS to Animate Elements
CSS Transforms
CSS transforms allow you to perform visual transformations on elements such as translation, rotation, scaling or skewing.
Translation
The translate transform lets you translate an element in space:
translate(tx, ty)
translateX(tx)
translateY(ty)For instance:
.move{
transform: translate(10px, 2em);
}See JsFiddle for a practical example.
Scaling
The scale transform allows you to scale elements:
scale(sx, sy)
scaleX(sx)
scaleY(sy)For instance:
.scale{
transform: scale(2, 0.5);
}See JsFiddle for a practical example.
Rotation
The rotate transform allows you to rotate elements:
rotate(deg)For instance:
.rotate{
transform: rotate(30deg);
}See JsFiddle for a practical example.
Skewing
The skew transform allows you to skew elements:
skew(anglex, angley)
skewX(angle)
skewY(angle)For instance:
.skew{
transform: skew(10deg, 10deg);
}See JsFiddle for a practical example.
Combining Transformations
You can also combine transforms together:
.move-and-rotate{
transform: translate(100px, 50px) rotate(50deg);
}
See JsFiddle for a practical example.
3D Transforms
In addition to the 2D transforms above, css transforms also provides support for 3D transforms by adding the z axis to the previous transforms:
translate3d(tx, ty, tz)
translateZ(tz)
rotate3d(rx, ry, rz, deg)
rotateZ(deg)
scale3d(sx, sy, sz)
/* etc... */
CSS Transitions
Transitions provides a very simple API to control the animation behavior of changing CSS styles. By using transitions you can provide smooth animations while elements transition between CSS style states instead of reflecting these changes in style immediately.
CSS transitions allow you to specify which property to animate, how long the animation will take and how the transition itself will run (will timing function to use, i.e. linear, fast an the beginning and slowly at the end, etc):
.becomes-opaque{
opacity: 0.5;
transition: opacity 1s linear;
}
.becomes-opaque:hover{
opacity: 1;
}
You can see this example on jsfiddle. The complete rule with all its options looks like this:
transition: none | <property> <time> <timing-function> <delay>
Note that you cannot animate all css properies in the universe. This is a list of the css properties that you can animate.
You can also animate multiple properties via css transitions at the same time. For instance:
.becomes-opaque{
opacity: 0.5;
transition: opacity 1s, transform .35s ease-in-out;
}
.becomes-opaque:hover{
opacity: 1;
transform: translateX(50px);
}
Check this example at jsfiddle. Finally you can transition all properties using all.
CSS Animations
CSS animations bring you one step further from css transitions and allow you to design finely grained animations between different css styles that can affect an element or multiple elements. They are composed of a style that describes the animation itself with the animation CSS rule and a series of keyframes that describe the animation frame by frame:
.infinite-fade-out{
animation: infinite-fadeout 5s infinite;
}
@keyframes infinite-fadeout{
from { opacity: 0; }
to {opacity: 1;}
}
// also
@keyframes infinite-fadeout{
0% { opacity: 0; }
50% {opacity: .75;}
100% {opacity: 1;}
}The full short-hand notation for the animation property is:
.myanimation{
animation: <name> <duration> <timing-function> <delay> <iteration-count> <direction> <fill-mode> <play-state>;
}
// example
.myanimation{
animation: move 4s linear 0s infinite alternate [none] [running];
}
CSS Layout
Display
The display property in CSS is the most fundamental way to manage layout in CSS. display controls how an element, and sometimes even its children, are laid out within a web page. The display property can take these different values:
block: Element generates a block element box with line breaks before and after the element. A block element will normally take the full width of the viewport unless specified otherwise.inline: Element generates an inline element box without line breaks. If we add another inline element it will be laid out in the same line that the first inline element as long as there’s enough space.inline-block: Element generates an block element box that will be flowed with its surrounding content as if it were an inline element.flex: Element behaves like a block element and lays out its content with flexbox.inline-flex: Element behaves like an inline element and lays out its content with flexbox.grid: Element behaves like a block element and lays out its conent with CSS grid.inline-grid: Element behaves like an inline element and lays out its content with CSS gird.none: Element is not displayed.
For more display values take a look at MDN.
Containing block
An element size and position is often affected by its containing block, the content area defined by the nearest block-level ancestor. This content area follows the box model and is determined by the original size of the block-level element minus any margin, border and padding defined in that element.
There are some exceptions as to what becomes the containing block of an element:
- When
position: absolute, the containing block is the padding box of the nearest positioned ancestor. - When
position: fixed, the containing block is defined by the viewport - When
position: absoluteorfixed, the containing block can also be defined by the nearest ancestor with atransform,filterorperspective
Position
Another important property in CSS layouts is position. The position property determines how an element is positioned within a document. Based on the type of position, we can use the top, right, bottom and left properties to determine the final location of the element. The position property can take these values:
static: (This is the default). Element is positioned according to the normal flow of the document. Any additional position propertiestop,right, etc have no effect.relative: Element is positioned according to the normal flow of the document with an offset that is relative to itself based on thetop,right,bottomandleftvalues.absolute: Element is removed from the normal flow of the document and no space is created for the element in the layout (this means that it may overlay other elements). The element is positioned in relation to its nearest positioned ancestor (ancestor that has a position other thanstatic) using thetop,right,bottomandleftvalues.fixed: Element is removed from the normal flow of the document and no space is created for the element in the layout (this means that it may overlay other elements). The element is positioned in relation to the containing block established by the viewport using thetop,right,bottomandleftvalues. If there’s an ancestor withtransform,perspectiveorfilterthen the containing block created by that ancestor is used instead of the viewport.sticky: element is positioned according to the normal flow of the document with an offset relative to its nearest scrolling ancestor using the values oftop,right,bottom, andleft. The sticky element will stick to the nearest ancestor that has a scrolling mechanism (created when theoverflowproperty has a value ofhidden,scroll,autooroverlay) even if that ancestor isn’t the nearest ancestor with actual scrolling behavior. The observable behavior of a sticky element is that it is initally positioned like a relative positioned element and once its containing block crosses a specific threshold (e.g. defined bytop) it sticks to the viewport until it reaches the end of the containing block.
For a more hands-on experimenting with CSS positionining play with this codepen and for more information about the position CSS property refer to MDN.
Issues with position: sticky
The position: sticky isn’t well supported in all browsers and it may not work under some scenarios:
- When the
overlayproperty is different fromvisiblein any its parent elements and that ancestor doesn’t have a height set
Issues with position: fixed
The position: fixed may not work in some scenarios:
- When there’s a
transformdefined in any of its parent elements.
Flexbox
The display: flex CSS rule lets you build CSS layouts using flexbox. For more information about CSS flexbox take a look at “Building flexible layouts with flexbox”.
Grid
The display: grid CSS rule lets you build CSS layouts using CSS Grid. For more informationa about CSS grid take a look at the CSS grid notebook.
Multicolumn layout
The CSS multicolumn layout allows you to define layouts with multiple columns of text a la newspaper. You enable this type of layout by using either the column-count property that specifies the number of columns to use, or the column-width property that specifies the width of the columns:
article{
column-count: 3;
}article {
column-width: 20em;
}You can use the following properties to configure the columns in different fashions:
columns, you can use thecolumnsshorthand to specify eithercolumn-width,column-countor both- the browser will calculate the optimal height of the multiple column layout but you can specify
heightormax-heightif you wish to have more control - the
column-gapproperty allows you to specify the gap between columns. - the
column-rulecreates a rule(line) between columns - the
column-spanmakes it possible for an element to span across all columns when its value is set toall(for instance, this would be helpful for a header element) - the
column-filldetermines how the content is particioned into columns. The content can either bebalanceas in all columns will have the same height orautowhich will make the layout take up the room the content needs.
CSS Regions
CSS Regions are an interesting concept in which you define your content using semantic HMTL 5 elements as usual but, instead of styling this elements with a specific layout directly, you use a specific set of non-semantic elements to define the layout and flow the content from the semantic elements into the layout elements. In order to do this you use flow-into to mark the elements with content:
.content{
flow-into: mycontent
}And the flow-from css property to mark the elements that represent the layout.
.layout{
flow-from: mycontent
}Where the mycontent is an identifier that connects content with layout.
For more information about css regions look into this article at dev.opera.
Awesome CSS References
- CSS Basics
- Animating stuff with CSS
- Layout

Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.
