Start

CSS rules and selectors

@MaximeEuziere, Stéphane Erard
September 2014

Definitions

CSS rules


selector {
  property: value;
  property: value;
  ...
}

CSS at-rules


@media XYZ {
  /* CSS rules for the media XYZ */
}

@font-face {
  font-family: XYZ;
  /* CSS properties for the custom font XYZ */
}

@keyframes XYZ {
  0% { /* CSS properties for the animation XYZ's start */ }
  50% { /* CSS properties for the animation XYZ's middle */ }
  100% { /* CSS properties for the animation XYZ's end */ }
}

etc.

Where can we write CSS code?

In a CSS file referenced in the page's head


style.css:
selector {
property: value;
property: value
}


HTML file:
<link rel=stylesheet href=style.css>

In a <style> element (in the page's head or body)


<style>
selector {
  property: value;
  property: value
}
</style>

Directly on a HTML element, using a style attribute (and no selector)


<div style="property: value; property: value;">
Hello World
</div>

You can even use CSS without any HTML code!

Demo
Explanation

Where should we write CSS code?

Static CSS

  • in a CSS file referenced in the page's head
  • uses caching
  • blocks the page rendering until it's loaded (avoids FOUC)



Dynamic CSS (edited by JS)

  • inline

How can we target HTML elements with CSS?

Universal selector



type (tag) selector



ID selector



class selector



attribute selectors (IE7+)

HTML:
<div attr=foo> Hi! </div>

CSS:
[attr] { color: red }      /* "attr" attribute is present */
[attr=foo] { color: red }  /* attr has the value "foo" */

How should we target HTML elements with CSS?

In CSS resets

  • Universal selector
  • Type selector



Everywhere else

  • Class selector
  • Type selector (carefully)

Which pseudo-classes can we use?

:link, :visited

CSS:
a:link { color: green }
a:visited { color: green }

Demo:

visit me

:hover

(IE6+ for <a>, IE7+ for all elements)

CSS:
a:hover { color: red }

Demo:

hover me

:active

(IE8+)

CSS:
input:active { color: red }

Demo:

:focus

(IE8+)

CSS:
input:focus { color: red }

Demo:

:checked

(IE9+)

CSS:
input:checked { outline: 5px solid red }

Demo:

:enabled, :disabled

(IE9+)

HTML:
<input>
<input disabled>

CSS:
input:enabled { color: green }
input:disabled { color: red }

Demo:

:target

(IE9+)

CSS:
div:target { background: red }

Demo:

Target

Which combinators can we use?

descendant combinator

HTML:
<div class=foo>
<div>
<div> Hi! </div>
</div>
</div>

CSS:
.foo div { border-color: red }

Demo:

Hi!

child combinator (IE7+)

HTML:
<div class=foo>
<div>
<div> Hi! </div>
</div>
</div>

CSS:
.foo > div { border-color: red }

Demo:

Hi!

Next-sibling combinator (IE7+)

HTML:
<div> A </div>
<div class=foo> B </div>
<div> C </div>
<div> D </div>

CSS:
.foo ~ div { border-color: red }

Demo:

A
B
C
D

Following-sibling combinator (IE7+)

HTML:
<div class=foo> A </div>
<div> B </div>
<div> C </div>

CSS:
.foo + div { border-color: red }

Demo:

A
B
C

selector list

HTML:
<div id=foo></div>
<div id=bar></div>

CSS:
#foo, #bar { color: red }

multiple selectors (IE7+)

HTML:
<div id=foo class="bar baz"></div>

CSS:
#foo.bar.baz { color: red }

And many more!


Link

:not(X) { ... }

:matches(X) { ... }

:has(X) { ... }

:dir(X) { ... }

:lang(X) { ... }

:any-link { ... }

:scope { ... }

:current { ... }

:current { ... }

:past { ... }

:future { ... }

:active-drop { ... }

:valid-drop { ... }

:invalid-drop { ... }

:read-only { ... }

:read-write { ... }

:placeholder-shown { ... }

:default { ... }

:indeterminate { ... }

:valid { ... }

:invalid { ... }

:in-range { ... }

:out-of-range { ... }

:required { ... }

:optional { ... }

:root { ... }

:empty { ... }

:blank { ... }

:nth-child(X)  { ... }

:nth-child(X of Y)  { ... }

:nth-last-child(X)  { ... }

:nth-last-child(X of Y)  { ... }

:first-child { ... }

:last-child { ... }

:only-child { ... }

:nth-of-type(X) { ... }

:nth-last-of-type(X) { ... }

:first-of-type { ... }

:last-of-type { ... }

:only-of-type { ... }

:nth-column(X) { ... }

:nth-last-column(X) { ... }

X || Y { ... }

[foo=bar i] { ... }

[foo~=bar] { ... }

[foo^="bar"] { ... }

[foo$="bar"] { ... }

[foo*="bar"] { ... }

[foo|="bar"] { ... }

Also, pseudo-elements

X:before { /* dummy element at the beginning of X (IE8+) */ }

X:after { /* dummy element at the end of X (IE8+) */ }

X::first-letter { /* targets only the first letter of X (IE5+) */ }

X::first-line { /* targets only the first line of X (IE5+) */ }

X::selection { /* targets user-selected text (IE9+) */ }

How are priorized CSS rules?

If you use the same selector:
lowest priority on "top", highest priority on "bottom"

<style>

.class { color: green; }

.class { color: blue; }

.class { color: red; }

</style>


color will be red.

If you use different selectors...

<style>

body div#id span a.class { color: blue }

body.bodyclass div.divclass span[name=foo] a.class { color: red }

</style>


color will be ... ???

Selectors specificity

Selectors specificity is computed using 4 counters:


  • If the element has inline styling, apply 1,0,0,0
  • For each ID value, apply 0,1,0,0 points
  • For each class value (or pseudo-class or attribute selector), apply 0,0,1,0 points
  • For each element reference, apply 0,0,0,1 point

Selectors specificity

Example:

Selectors specificity

Example:

Selectors specificity

Example:

Selectors specificity

  • Universal selector ( * ) doesn't count
  • Pseudo-elements have a score of 0,0,0,1
  • Adding !important after a value makes it stronger than all the others, regardless of the selector's specificity.

Good practices

  • Use only classes and pseudo-classes
  • Keep your selectors short (2-3 classes max)
  • Adopt a naming methodology...

The BEM methodology

http://bem.info/

BEM stands for Block-Element-Modifier
It describes how to write your HTML code and how to chose your CSS classes in a clean and maintenable way.

The BEM methodology: Blocks

A block is an independent entity, a "building block" of an application.
A block can be either simple or compound (containing other blocks).

Example:
Search form block

The BEM methodology: Elements

An element is a part of a block that performs a certain function.
Elements are context-dependent: they only make sense in the context of the block they belong to.

Example:
An input field and a button are elements of the Search Block


Menu items are elements of the Menu block


HTML:
<ul class="menu">
  <li class="menu__item">…</li>
  <li class="menu__item">…</li>
</ul>

The BEM methodology: Modifiers

Block Modifiers:
We often need to create a block very similar to an existing one, but with slightly altered its appearance or behavior.

Example:
Header menu / Footer menu



HTML
<ul class="menu menu--tabs">
  ...
</ul>
...
<ul class="menu menu--buttons">
  ...
</ul>


.menu {
  // Common style
}

.menu__item {
  // Common style
}

.menu--tabs {
  // Specific style
}

.menu--buttons {
  // Specific style
}

The BEM methodology: Modifiers

Element Modifiers:
Example:
Current menu item
<ul class="menu">
  <li class="menu__item">...</li>
  <li class="menu__item menu__item--current">...</li>
  <li class="menu__item">...</li>
</ul>


.menu__item {
  // Items style
}

.menu__item--current {
  // Current item style
}

Bonus

CSS selectors can use Unicode characters

It's W3C valid and it works on IE6+ !
.❤ { color: pink }
.🍎 { color: red }
.☕ { color: #C0FFEE }
.💪 { color: #BADA55 }
.💩 { color: brown }


More details in this website and this video!

We can make almost anything interactive with just CSS and no JS

Examples:

Bootleg: reinventing Bootstrap components in pure CSS

CSSSlider, used to make this slider.

Thanks!

Questions?