CSS fundamentals

jared anderson

what is css?

a language for specifying how web documents are presented to users

CSS

  1. browser: user software used to consume the web
  2. document: a structured text file parsed by users' browser (HTML, XML or SVG)
  3. stylesheet: tells browser how to present the document to the person

the traditional web

https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/How_CSS_works

grab doc

how it works

dom?

  • The browser converts HTML and CSS into the DOM.
  • The DOM represents the document in the computer's memory.
  • It combines the document's content with its style.
  • The browser displays the contents of the DOM

document object model: a tree-like structure where each element, attribute, and text become a DOM node in the structure

<p>
  Let's use:
  <span>Cascading</span>
  <span>Style</span>
  <span>Sheets</span>
</p>
P
├─ "Let's use:"
├─ SPAN
|  └─ "Cascading"
├─ SPAN
|  └─ "Style"
└─ SPAN
   └─ "Sheets"

you write

browser parses

<p>
  Let's use:
  <span>Cascading</span>
  <span>Style</span>
  <span>Sheets</span>
</p>

document

p

"Let's use:"

span

span

span

"Cascading"

"Style"

"Sheets"

creating structure

span {
    background: orange;
}

document

p

"Let's use:"

span

span

span

"Cascading"

"Style"

"Sheets"

css lets you "select" and style specific nodes

span {
  border: 1px solid black;
  background-color: lime;
}

+

=

css

vocabulary

.my-class {

    background: blue;

    color: white;

}

parts

selector

property

value

declaration

rule

rule

@import 'custom.css';

/* other at-rules:

@charset
@media
@document
@font-face
@supports

*/

at-rules

@media (min-width: 801px) {
  body {
    margin: 0 auto;
    width: 800px;
  }
}

nested statements

statements

/* stylesheet.css */

@import 'custom.css';

@media (min-width: 801px) {
  body {
    margin: 0 auto;
    width: 800px;
  }
}

stylesheet

Q:

  • Approximately how many CSS properties are there?
  • How many stylesheets can one document contain?
  • How many stylesheets should one document contain?

A:

  • 300+
  • Practically unlimited
  • Traditionally, as few as possible to limit network requests (a browser bottleneck)

properties, values & units

some memorization required

  • 300+ properties
  • "many" units (value types)
    • numeric-based (em, px, %, rem, vh, etc)
    • color-based: (rgb, rgba, hex, etc)
    • functions: (calc, color functions, url, etc)
    • more...
  • infinite number of possible values
  • something you'll need to learn for yourself

w3schools mdn is your best reference

syntax

comma separated

whitespace

  • spaces, tabs and new lines

  • added for readability

  • browser tends to ignore much of the whitespace inside your CSS

@media (min-width: 70em) {

  body {

    font-size: 130%;

  }

}
@media (min-width: 70em) { body {font-size: 130%;} }

=

comments

Comments in CSS begin with /* and end with */.

shorthand properties

group of related properties -> shorthand property allowing you to set all related property values in a single declaration

shorthand properties

.my-class {
    padding-top: 10px;
    padding-right: 15px;
    padding-bottom: 15px;
    padding-left: 5px;
}

.my-class {
    padding: 10px 15px 15px 5px;
}

shorthand properties

.my-class {
    background-color: red;
    background-image: url(bg-graphic.png);
    background-position: 10px 10px;
    background-repeat: repeat-x;
    background-scroll: fixed;
}

.my-class {
    background: red url(bg-graphic.png) 10px 10px repeat-x fixed;
}

shorthand properties

/*

shorthand properties:

font
background
padding
border
margin
flex
flex-flow

*/

selectors

selectors

  • selector is a declarative description describing which nodes in the tree to "select" and style
span.i-need-space {
    display: block;
    margin: 20vh 0;    
}

  • document is a tree structure with nodes

selectors

four categories

  1. simple
  2. attribute
  3. pseudo
  4. combinators

#1 simple selectors

match elements based on their element type, class, or id

type/element selectors

/* All p elements are red */
p {
  color: red;
}

/* All div elements are blue */
div {
  color: blue;
}
<p>Good morning.</p>

<div>Go away!</div>

class selectors

/*
The element with the
class "first" is bolded
*/
.first {
  font-weight: bold;
}

/*
All the elements with the class
"done" are strike through
*/
.done {
  text-decoration: line-through;
}
<ul>
    <li class="first done">
        Create an HTML document
    </li>
    <li class="second done">
        Create a CSS style sheet
    </li>
    <li class="third">
        Link them all together
    </li>
</ul>

id selectors

#polite {
  font-family: cursive;
}

#rude {
  font-family: monospace;
  text-transform: uppercase;
}
<p id="polite">
    "Good morning."
</p>

<p id="rude">
    "Go away!"
</p>

universal selector

* {
    padding: 5px;
}

#2 attribute selectors

match elements based on their attributes and attribute values

attributes?

<p data-qty="3" data-is-number>
    Three
</p>

<date timestamp="2017-01-11">
    January 11, 2017
</date>

attribute name

attribute value

  • [attr] : all elements with the attribute attr, whatever its value.
  • [attr=val] : all elements with the attribute attr, but only if its value is val.
  • [attr~=val]: all elements with the attribute attr, but only if the value val is one of a space-separated list of values contained in attr's value (for example a single class in a space-separated list of classes.)

presence & value attribute selectors

substring value attribute selectors

  • [attr|=val] : all elements with the attribute attr for which the value is exactly val or starts with val- (careful, the dash here isn't a mistake, this is to handle language codes.)
  • [attr^=val] : all elements with the attribute attr for which the value starts with val.
  • [attr$=val] : all elements with the attribute attr for which the value ends with val.
  • [attr*=val] : all elements with the attribute attr for which the value contains the string val (unlike [attr~=val], this selector doesn't treat spaces as value separators but as part of the attribute value.)
[data-vegetable] {
  color: green
}
Ingredients for my recipe:
<i lang="fr-FR">Poulet basquaise</i>
<ul>
    <li data-quantity="1kg" data-vegetable>
        Tomatoes
    </li>
    <li data-quantity="3" data-vegetable>
        Onions
    </li>
    <li data-quantity="3" data-vegetable>
        Garlic
    </li>
    <li data-quantity="700g" data-vegetable="not spicy like chili">
        Red pepper
    </li>
    <li data-quantity="2kg" data-meat>
        Chicken
    </li>
    <li data-quantity="optional 150g" data-meat>
        Bacon bits
    </li>
    <li data-quantity="optional 10ml" data-vegetable="liquid">
        Olive oil
    </li>
    <li data-quantity="25cl" data-vegetable="liquid">
        White wine
    </li>
</ul>
[data-vegetable="liquid"] {
  background-color: goldenrod;
}
[data-vegetable~="spicy"] {
  color: red;
}
[lang|=fr] {
  font-weight: bold;
}
[data-vegetable*="not spicy"] {
  color: green;
}
[data-quantity$="kg"] {
  font-weight: bold;
}
[data-quantity^="optional"] {
  opacity: 0.5;
}

#3 pseudo-classes

& pseudo-elements

these don't select actual elements, but rather certain parts of elements, or elements only in certain contexts.

pseudo-classes

  • a keyword preceded by a colon (:)
  • added on to the end of selectors
  • selected elements only when in a certain state.

pseudo-classes example

/* These styles will style our link
   in all states */
a {
  color: blue;
  font-weight: bold;
}

/* We want visited links to be the same color
   as non visited links */
a:visited {
  color: blue;
}

/* We highlight the link when it is
   hovered (mouse), activated
   or focused (keyboard) */
a:hover,
a:active,
a:focus {
  color: darkred;
  text-decoration: none;
}

pseudo-classes

pseudo-elements

  • keywords preceded by two colons (::)
  • added to the end of selectors
  • selects a certain part of an element.

pseudo-elements example

/*
All elements with an attribute "href", which values
start with "http", will be added an arrow after its
content (to indicate it's an external link)
*/

[href^=http]::after {
  content: '⤴';
}

pseudo-elements

#4 combinators

 combining selectors to perform more fine-grained selections

combinator syntax

Combinators Select
AB matches both A and B at the same time.
A B matching B that is a descendant of an element matching A
A > B matching B that is a direct child of an element matching A
A + B matching B that is the next sibling of an element matching A
A ~ B matching B that is among the next sibling of an element matching A 

combinators pop quiz

table td, table > th {}

table thead th {}

table tbody td + td {}

table tbody td:last-child {}

.with-currency[lang="fr"] td:last-child::after {
  content: ' €';
}

.thumbnail.is-big {
    transform: scale(2);
}

the cascade

css, multiple inheritance & property conflict resolution

<p>
    <span class="one">
        Cascading
    </span>

    <span id="two" class="span two">
        Style
    </span>
    
    <span class="three">
        Sheets
    </span>
</p>
span {
  color: purple;
}

#two {
    color: blue;
}

p:first-child span.two.two:nth-child(2) {
    color: red;
}

span:nth-child(2) {
    color: yellow;
}

* {
    color: orange;
}

(not rule)

conflict resolution

the selector that wins out in the cascade depends on these three factors, listed in order of weight (least to most):

  1. Source order
  2. Specificity
  3. Importance

#1 source order

p {
    color: red;
}

p {
    color: blue;
}

when everything else is equal, rules defined later in a stylesheet win over rules defined beforehand.

#2 specificity

  • a measure of how specific a selector is, in terms of how many elements it could match.
  • the more specific a selector -- the fewer items it will match -- the more weight that rule has.
  • The amount of specificity a selector has is based on something called the selector weight.
  • selector weight has four different values, which can be thought of as thousands, hundreds, tens and ones:

 0030 > 0009

#2 specificity

selector weight

  • 1000s: 1 if the declaration is contained within a <style> tag or as part of a style attribute. Otherwise, 0.
  • 100s: 1 for each id selector contained within the overall selector.
  • 10s: 1 for each class selector, attribute selector or pseudo-class contained inside the overall selector.
  • 1s: 1 for each element selector and pseudo-element contained inside the overall selector

 Universal selector (*), combinators (+, >, ~, ' ') and negation pseudo-class (:not) have no effect on specificity.

#2 specificity

selector weight

#2 specificity

💩

if you are having specificity battles, that should be a smell that something is wrong. 

consider adopting a system or strategy like CSS modules, BEM, atomic, ITCSS, OOCSS

#3 importance

don't use it!!!1

.💩 {
    display: none !important;
}

conflict resolution

The only way to override this !important declaration would be to include another !important declaration of the same specificity, later in the source order.

conflict resolution

recap

 

  1. Source order
  2. Specificity
  3. Importance

conflict resolution system

100,000s

10,000s

1,000s

100s

10s

1s

!important

<style> style=

# id selectors

# class, pseudo class, attribute selectors

# element, pseudo-element selectors

source order

inheritance

some property values are inherited. some are not.

¯\_(ツ)_/¯

"common sense" is your reference. Or this:

https://developer.mozilla.org/en-US/docs/Web/CSS/Reference

controlling inheritance

set the value of property to adjust inheritance behavior

  • inherit: be the same as that of its parent element.
  • initial: be the same as the value set for that element in the browser's default style sheet
  • unset: resets the property to its natural value, which means that if the property is naturally inherited it acts like inherit, otherwise it acts like initial.

box  model

box model

  • the foundation of layout on the Web
  • each element is represented as a rectangular box
  • each box's content, padding, border, and margin built up around one another like the layers of an onion
  • as browser renders, it works out what styles are applied to the content of each box
    • how big
    • where boxes sit in relation to one another
    • etc

box model

  • width/height: set the width and height of the content box (text content and other boxes)
  • padding: layer between the outer edge of the content box and the inner edge of the border.
  • border: layer between the outer edge of the padding and the inner edge of the margin
  • margin: outer area surrounding the CSS box, which pushes up against other CSS boxes

box types

  • many different box types which changes the behavior
  • box type changed by the `display` property
    • block
    • inline
    • inline-block
    • flex
    • etc

must do

*, *:before, *:after {
  box-sizing: border-box;
}

https://css-tricks.com/box-sizing/

challenges

what makes CSS hard?

  • memorization required
    • 300+ properties and growing
    • always shifting browser support landscape
  • knowing what is possible
    • foundational knowledge required
  • hard to scale
    • managing globals
    • managing the cascade
    • specificity wars
  • acquiring unorganized stylesheets

leveling up

improving at CSS

  • write more CSS

scaling

the cascade and inheritance model are awesome until they're not...

strategies, conventions & tech

  • atomic design
  • ITCSS
  • CSS modules
  • BEM
  • OOCSS
  • etc

philosophy behind ITCSS

  • settings: variables, definitions, etc (no output)
  • tools: functions / mixins (no output)
  • generic: resets, normalizations
  • elements: base styles for "unclassed" elements (eg: H1 default styles)
  • objects: class-based styles for elements (eg: diff types of H1)
  • components: grouping components together (ie: widgets, patterns)
  • trumps: nuclear overrides

philosophy behind ITCSS

  • reach: top of triangle affects / has potential to affect more elements
  • specificity: increase in specificity the further down the triangle
  • explicitness: from (top) generic, low-level, unremarkable to (bottom) scoped and specific rules

the end :)

references

CSS Fundamentals

By Jared Anderson

CSS Fundamentals

  • 1,530