jared anderson
a language for specifying how web documents are presented to users
https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/How_CSS_works
grab doc
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
.my-class {
background: blue;
color: white;
}
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
/* stylesheet.css */
@import 'custom.css';
@media (min-width: 801px) {
body {
margin: 0 auto;
width: 800px;
}
}
comma separated
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 in CSS begin with /* and end with */.
group of related properties -> shorthand property allowing you to set all related property values in a single declaration
.my-class {
padding-top: 10px;
padding-right: 15px;
padding-bottom: 15px;
padding-left: 5px;
}
.my-class {
padding: 10px 15px 15px 5px;
}
.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:
font
background
padding
border
margin
flex
flex-flow
*/
span.i-need-space {
display: block;
margin: 20vh 0;
}
four categories
match elements based on their element type, class, or id
/* All p elements are red */
p {
color: red;
}
/* All div elements are blue */
div {
color: blue;
}
<p>Good morning.</p>
<div>Go away!</div>
/*
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>
#polite {
font-family: cursive;
}
#rude {
font-family: monospace;
text-transform: uppercase;
}
<p id="polite">
"Good morning."
</p>
<p id="rude">
"Go away!"
</p>
* {
padding: 5px;
}
match elements based on their attributes and attribute values
<p data-qty="3" data-is-number>
Three
</p>
<date timestamp="2017-01-11">
January 11, 2017
</date>
attribute name
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;
}
these don't select actual elements, but rather certain parts of elements, or elements only in certain contexts.
/* 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;
}
/*
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: '⤴';
}
combining selectors to perform more fine-grained selections
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 |
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);
}
<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)
the selector that wins out in the cascade depends on these three factors, listed in order of weight (least to most):
p {
color: red;
}
p {
color: blue;
}
when everything else is equal, rules defined later in a stylesheet win over rules defined beforehand.
0030 > 0009
selector weight
Universal selector (*), combinators (+, >, ~, ' ') and negation pseudo-class (:not) have no effect on specificity.
selector weight
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
.💩 {
display: none !important;
}
The only way to override this !important declaration would be to include another !important declaration of the same specificity, later in the source order.
recap
!important
<style> style=
# id selectors
# class, pseudo class, attribute selectors
# element, pseudo-element selectors
source order
set the value of property to adjust inheritance behavior
*, *:before, *:after {
box-sizing: border-box;
}
https://css-tricks.com/box-sizing/