Topics for today
- DRY
- Selectors
- Custom properties for cascading variables
- Generated content
- Cascading and Inheritance
Follow along at designftw.mit.edu/go/slides
Every piece of knowledge must have a single, unambiguous, authoritative representation within a systemThe Pragmatic Programmer, Andy Hunt and Dave Thomas
def right_triangle_perimeter(a, b, c):
return a + b + c
# ... later on
p = right_triangle_perimeter(3, 4, 5)
from math import sqrt
def right_triangle_perimeter(a, b, c):
return a + b + sqrt(a**2 + b**2)
# ... later on
p = right_triangle_perimeter(3, 4)
.red-button {
background: hsl(0, 80%, 90%);
}
.primary-button {
background: hsl(0, 80%, 90%);
}
button {
border-radius: 5px;
padding: 5px 12px 6px;
font-size: 24px;
line-height: 24px;
}
button.large { font-size: 46px; }
button {
border-radius: .2em;
padding: .2em .5em .25em;
font-size: 100%;
line-height: 1;
}
button.large { font-size: 200%; }
.tab {
border-radius: .3em .3em 0 0;
padding: .1em .5em .1em .5em;
margin: 0 .1em 0 .1em;
}
.tab {
border-radius: .3em;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
padding: .1em .5em;
margin: 0 .1em;
}
Three strikes and you refactor
Duplication is far cheaper than the wrong abstractionSandy Metz
h1 {
font-size: 300%;
line-height: 1;
}
h1 headings.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
* {font-weight: normal} might seem like a reasonable default, but it means our strong elements also will start from the same non-bold baseline.#about<section id="about">
<main id="about">
<section id="about-me">
<input name="about">
.notice<p class="tip notice">
<div class="notice">
<p class="important notice warning">
<notice>
<p class="foo">
<div class="warning-notice">
[href]<a href="http://designftw.mit.edu">
<a href>
<link rel="stylesheet" href="style.css">
<a>
<a hreflang="fr">
[type="range"]<input type="range">
<yolo type="range">
<input type="number">
First view:
ul? We could give it a different class name, OR we could concatenate two simple selectors (ul and .minimal) to intersect.Second view:
p.notice.tip[title]#tip42
.notice.tip[title]p#tip42
button:hover {
background: greenyellow;
}
:hover:focus:checked:target:first-child:last-child:only-child:nth-child(odd)p:nth-last-of-type(4n + 8):*-child family of pseudo-classes.:first-child and :last-child match elements who are first and last among their siblings, respectively.:only-child is equivalent to :first-child:last-child:nth-child() is a generalization. It accepts an argument of the form An+B (e.g. 2n+1)
and matches elements whose position among their siblings matches the argument for some non-negative integer n.
A and B can be negative.
:nth-child(even) is equivalent to :nth-child(2n) and matches each 2nd, 4th, 6th etc child.:nth-child(odd) is equivalent to :nth-child(2n+1) and matches each 1st, 3rd, 5th etc child.:nth-child(3n+1) matches every 3rd child starting from the first.:nth-child(1) is equivalent to :first-child:nth-last-child() is exactly the same as :nth-child() but starts counting from the end.
:nth-last-child(1) is equivalent to :last-child:*-of-type family of pseudo-classes, with exactly the same syntax, that only counts elements of the same type.
You can experiment with it here:not()
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:not(:hover) {
text-decoration: none;
}
:isfooter aa anywhere inside footer
ol.tasks > li:checked + labellabel directly after a or
label that contains a or
label after or
h1 ~ h2h2 that comes after a sibling h1
<section>
<h2>
<h2>
<h1>
h1s that come before h2s”, (e.g. h1, h2)button.primary):not(:only-child)):not() can only contain simple selectors. E.g. code:not(pre code) is not expressable.-- and behave like normal CSS properties.var() function and we can use that anywhere (including inside calc()), except inside url().::marker allows us to style list markersfilter: hue-rotate(240deg) fails, because ::marker does not support filter.
(Applying it on the li works fine)
::before emulates a text node inserted in the beginning of an element and ::after a text node inserted after every other child.::before::before is invalid (though there are discussions about enabling it in the future).*) has higher priority than any UA stylesFirst view:
li, strong and em elements have the same font, font size, color as the entire list, but not the same background or padding. Why?Second view:
strong element doesn't inherit it.Third view:
inherit to inherit from a non-inherited property.initial.inherit keyword can come in handy.inheritstyle attribute, it wins#id selectors wins.classes, :pseudo-classes (except :not()), [attributes]. The selector with the most wins.:not()) (= B).foo.foo.foo:not(#nonexistent)#foo to [id="foo"]:where()