CSS
Table of Contents
CSS Selectors
Basic Selectors
- Type selector: Select elements by their type. Ex:
a
,p
,div
will select all elements of typea
,p
anddiv
respectively - Id selector: Select elements by their id. Ex:
#john-doe
will select any element with idjohn-doe
,div#john-doe
will select adiv
element with#jonh-doe
id - Descendant selector: Select an element inside another element. Ex:
p strong
will select allstrong
elements inside ap
element,ul li#john-doe
will select theli#john-doe
element within aul
element,ul#people li
will select allli
elements within aul#people
element. - Class selector: Select elements with a given class. Ex:
li.spanish
will select allli
elements with.spanish
class,.spanish
will select all elements with.spanish
class - 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
class
attribute value is equal tonews
: E[class=“news”] - Select an paragraph whose
class
attribute value is a list of whitespace separated values and one of which isnews
: E[class~=“news”] - Select an paragraph whose
class
attribute value begins withbar
: E[class^=“news”] - Select an paragraph whose
class
attribute value ends withbar
: E[class$=“news”] - Select an paragraph whose
class
attribute value contains the substringbar
: E[class*=“news”] - Select an paragraph whose
class
attribute 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-line
selects the first line of ap
element. 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.::before
and::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 anyli
element.
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 indexn
within 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 thatn
within 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 indexn
within 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: 0
andvisibility:hidden
are 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: absolute
orfixed
, the containing block can also be defined by the nearest ancestor with atransform
,filter
orperspective
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
,bottom
andleft
values.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
,bottom
andleft
values.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
,bottom
andleft
values. If there’s an ancestor withtransform
,perspective
orfilter
then 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 theoverflow
property has a value ofhidden
,scroll
,auto
oroverlay
) 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
overlay
property is different fromvisible
in 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
transform
defined 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 thecolumns
shorthand to specify eithercolumn-width
,column-count
or both- the browser will calculate the optimal height of the multiple column layout but you can specify
height
ormax-height
if you wish to have more control - the
column-gap
property allows you to specify the gap between columns. - the
column-rule
creates a rule(line) between columns - the
column-span
makes 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-fill
determines how the content is particioned into columns. The content can either bebalance
as in all columns will have the same height orauto
which 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.