Pro-tip: Press space bar to progress and it won't skip any slides
For Practical Peoples
Prologue
Part 1
1px
100px
.box {
width: 60px;
height: 60px;
background: deepskyblue;
}
.box
1px
!== 1 pixel on the screen1px
= 1 pixel * ScreenDensityScreen pixel density usually ranges from:
1x, 1.25x, 1.5x, 2x, or 4x
1%
33.333%
150%
.parent {
border-color: gray;
border-style: dashed;
}
.box {
width: 50%;
background: deepskyblue;
}
.box
em
1em
= Calculated font-size
of current element
1em
1.25em
3em
.box {
width: 2em;
background: deepskyblue;
}
.box-2 {
font-size: 2em;
width: 2em;
background: palegreen;
}
.box
.box-2
.box {
/* font-size: 16px; (default) */
width: 2em; /* 2em = 16px * 2 = 32px */
background: deepskyblue;
}
.box-2 {
font-size: 2em; /* 2em = 16px * 2 = 32px */
/* The 32px font-size will then change what
2em on the width means */
width: 2em; /* 2em = 32px * 2 = 64px */
background: palegreen;
}
rem
1rem
= Calculated font-size
of html
element
1rem
1.25rem
3rem
.box {
width: 2rem;
background: deepskyblue;
}
.box-2 {
font-size: 2rem;
width: 2rem;
background: palegreen;
}
.box
.box-2
ex
and ch
Based on the font that renders
1ex
1.25ex
15ex
1ex
= Calculated width of a lower-case x
1ch
1.25ch
15ch
1ch
= Calculated width of the number 0
.box {
font-family: monospace;
width: 20ex;
background: deepskyblue;
}
.box-2 {
font-family: sans-serif;
width: 20ex;
background: palegreen;
}
Monospace Font:
Sans-Serif Font
vw
25vw
vh
25vh
vmin
25vmin
vmax
25vmax
mm
millimetercm
centimeterin
inchpt
pointpc
picaWhen size should be proportionate to the unit's basis
Sized with em
Sized with px
A fallback, if you can't/shouldn't use a relative unit.
Special styles for specific circumstances
@media /* Conditions */ {
/* CSS Rules */
}
@media screen { /* Computer Display CSS Rules */ }
@media print { /* Print CSS Rules */ }
Fun fact: speech
, braille
, embossed
(braille printers), tty
(like command line), tv
also exist.
@media (min-width: 768px) {
/* CSS Rules */
}
@media (min-width: 48em) and (min-height: 30em) {
/* CSS Rules */
}
@media (max-height: 500px) {
/* CSS Rules */
}
@media
Best Practices@media
queriesWrite min-width
and min-height
,
not max-width
or max-height
.box {
/* Mobile CSS */
}
@media (min-width: 48em) {
.box {
/* Decent size screen styles */
}
}
@media (min-width: 62em) {
.box {
/* Huge screen styles */
}
}
/* Widget Styles */
.widget { }
@media (min-width: 768px) {
.widget { }
}
/* Doo Dad Styles */
.doo-dad { }
@media (min-width: 768px) {
.doo-dad { }
}
@media (min-width: 768px) and screen {
/* Is screen necessary, do we want to exclude print? */
.widget { }
}
@media (min-width: 1024px) and (min-height: 768px) {
/* Is height necessary, should 750px tall screens be excluded? */
.widget { }
}
Devices can be a decent guide.
Test from 300px - 1600px wide.
This screenshot is faked
<strong>
& <em>
position: absolute, fixed, sticky
position: relative
top, right, bottom
or left
are set)transform
margin
or padding
* Except for fallbacks or if you know better options aren't wise
based on your user stats.
Floats are great for floating elements next to a bunch of text so it will wrap.
Lorem ipsum dolor sit amet, wakka un blitz and chips; dolla dolla bill. Lorem ipsum dolor sit amet, wakka un flurb dolla dolla bill. Lorem ipsum dolor sit amet, wakka un flurb dolla dolla bill. Lorem ipsum dolor sit amet, wakka un blitz and chips; dolla dolla bill. Lorem ipsum dolor sit amet, wakka un flurb dolla dolla bill. Lorem ipsum dolor sit amet, wakka un flurb dolla dolla bill.
Lorem ipsum dolor sit amet, wakka un blitz and chips; dolla dolla bill. Lorem ipsum dolor sit amet, wakka un flurb dolla dolla bill. Lorem ipsum dolor sit amet, wakka un flurb dolla dolla bill.
Basics and terminology
Great at 2 dimensional, custom, and large scale layouts
Element surrounding the grid.
Direct child element of a grid container
Any line in the grid
.grid-container {
display: grid;
grid-template-columns: 25% 50% 25%;
}
Grid code examples stolen/modified from GridByExample.com, from Rachel Andrew
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
grid-column-start: -3;
grid-column-end: -1;
grid-row-start: -2;
grid-row-end: -1;
grid-column-start: 1;
grid-column-end: -1;
Try to complete as many as you can on our break
(try at least 5):
.my-header {
grid-column: 1 / -1;
}
.my-content {
grid-column: 1 / span 2;
}
.my-sidebar {
grid-row: 2;
grid-column: 3;
}
grid-template-areas
Name regions in your grid.
.grid-container {
display: grid;
grid-template-columns: 25% 50% 25%;
grid-template-areas:
"header header header"
"content content sidebar"
"footer footer footer";
}
grid-area
Set location of grid items to a grid region.
.my-header { grid-area: header; }
.my-content { grid-area: content;}
.my-sidebar { grid-area: sidebar;}
.my-footer { grid-area: footer; }
.grid-container {
display: grid;
grid-template-columns: 50% 50%;
grid-template-areas:
'header header'
'content content'
'sidebar footer';
}
fr
Distributes free space in a grid track
grid-template-row: 1fr 50% 1fr;
1fr 1fr /* 50% 50% (Maybe) */
1fr 2fr 1fr /* 25% 50% 25% (Maybe) */
25% 1fr 1fr /* 25% 37.5% 37.5% (Maybe) */
minmax()
display: grid;
grid-gap: 10px;
grid-template-columns:
minmax(200px, 1fr) 200px 200px;
repeat(number, size)
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(4, 100px);
grid-template-rows: repeat(3, auto);
auto-fit
and auto-fill
grid-template-columns: repeat(auto-fit, 150px)
grid-template-columns: repeat(auto-fill, 150px)
display: grid;
grid-template-columns:
repeat(auto-fit, minmax(180px, 1fr));
grid-gap: 1rem;
@supports (...) {}
Grid's bestie!.grid-container { /* Fallback styles */ }
@supports (display: grid) {
.grid-container {
display: grid;
grid-template-columns: 50% 50%;
grid-template-areas:
'header header'
'content content'
'sidebar footer';
}
}
You'd think...
.wrapper {
display: grid;
grid-template-columns: 25% 25% 25% 25%;
grid-gap: 10px;
}
.wrapper {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
grid-gap: 10px;
}
Fix the equal width grid with gutters yourself:
codepen.io/pen/RvBzrV
Try more CSSGridGarden.com
Or explore GridByExample.com
Basics and terminology
Best at 1 dimensional and small scale layouts.
Element enclosing everything
Direct child of flex container
The axis the flex items are laid out on (row/column).
The opposite axis of the main (column/row)
The beginning of the main axis is where items start from, end is the opposite side.
The beginning of the cross axis will be top if flex is horizontal, left if it's vertical
.flex-container {
display: flex; /* All you need */
/* flex-direction: row; (Default) */
/* flex-wrap: nowrap; (Default) */
}
flex-wrap
.flex-container {
display: flex;
/* flex-direction: row; (Default) */
flex-wrap: wrap;
}
flex-direction
.flex-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
Examples of flex-direction
justify-content
How extra space is distributed along the main axis
.flex-container {
display: flex;
justify-content: center;
}
justify-content
valuesjustify-content: flex-start;
justify-content: flex-end;
justify-content
valuesjustify-content: space-between;
justify-content: space-around;
justify-content: space-evenly;
align-items
How extra space is distributed along the cross axis
.flex-container {
display: flex;
align-items: center;
}
align-items
valuesalign-items: stretch; /* (Default) */
align-items: flex-start;
align-items: flex-end;
align-items
valuesalign-items: center;
align-items: baseline;
Try to complete as many as you can on our break
(try to get to exercise 10):
Hint: Having "A Complete Guide to Flexbox" from CSS-Tricks.com open in another browser may come in handy!
All of the previous properties applied to flex containers, these are for flex items.
order
Changes the visual order of the elements on the page.
.flex-item-3 {
order: 1;
}
order
is calculated like weight
in Drupal, heavier goes to the end, lighter goes to the top.
.flex-item-1 { /* Not set */ }
.flex-item-2 { order: -999; }
.flex-item-3 { order: 100; }
.flex-item-4 { order: 10; }
.flex-item-5 { /* Not set */ }
flex-basis
Sets initial size of flex item
.flex-item-3 { flex-basis: 4em; }
.flex-item-4 { flex-basis: 2em; }
flex-grow
Distributes extra space to items that have a value
.flex-item-3 { flex-grow: 2; }
.flex-item-4 { flex-grow: 1; }
flex-shrink
When there isn't enough space items will shrink to fit
.flex-item-3 { flex-shrink: 2; }
.flex-item-4 { flex-shrink: 1; }
margin
and flex items💖auto
will use left over space to push as far as it can
.flex-item-3 {
margin: auto;
}
Try styling a menu for an up and coming industrialist super-power:
codepen.io/pen/rPrERx
Hint: Having "A Complete Guide to Flexbox" from CSS-Tricks.com open in another browser may come in handy!
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum nibh diam, et rhoncus nulla interdum vitae. Suspendisse ac quam justo. In ut enim faucibus, aliquet velit a, rhoncus mauris. Ut pharetra magna ac euismod gravida. Aenean fringilla ex sit amet est condimentum, fermentum dapibus diam finibus. Donec id tortor turpis. Morbi semper turpis quis posuere sagittis. Suspendisse ac pulvinar magna, a hendrerit arcu. Aenean dictum nunc sit amet libero fringilla, vel vulputate risus auctor. Vestibulum interdum vulputate nibh et sodales. Donec lorem nisi, mattis quis tempus sed, finibus at velit. Curabitur pharetra libero eget felis ornare finibus. Vivamus eget sollicitudin risus, eu lobortis est. Duis sed lectus a purus luctus fermentum. Duis consequat gravida ex, id pellentesque turpis finibus eu.
.column-container {
column-count: 3;
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum nibh diam, et rhoncus nulla interdum vitae. Suspendisse ac quam justo. In ut enim faucibus, aliquet velit a, rhoncus mauris. Ut pharetra magna ac euismod gravida. Aenean fringilla ex sit amet est condimentum, fermentum dapibus diam finibus. Donec id tortor turpis. Morbi semper turpis quis posuere sagittis. Suspendisse ac pulvinar magna, a hendrerit arcu. Aenean dictum nunc sit amet libero fringilla, vel vulputate risus auctor. Vestibulum interdum vulputate nibh et sodales. Donec lorem nisi, mattis quis tempus sed, finibus at velit. Curabitur pharetra libero eget felis ornare finibus. Vivamus eget sollicitudin risus, eu lobortis est. Duis sed lectus a purus luctus fermentum. Duis consequat gravida ex, id pellentesque turpis finibus eu.
column-width
.column-container {
column-width: 9em;
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum nibh diam, et rhoncus nulla interdum vitae. Suspendisse ac quam justo. In ut enim faucibus, aliquet velit a, rhoncus mauris. Ut pharetra magna ac euismod gravida. Aenean fringilla ex sit amet est condimentum, fermentum dapibus diam finibus. Donec id tortor turpis. Morbi semper turpis quis posuere sagittis. Suspendisse ac pulvinar magna, a hendrerit arcu. Aenean dictum nunc sit amet libero fringilla, vel vulputate risus auctor. Vestibulum interdum vulputate nibh et sodales. Donec lorem nisi, mattis quis tempus sed, finibus at velit. Curabitur pharetra libero eget felis ornare finibus. Vivamus eget sollicitudin risus, eu lobortis est. Duis sed lectus a purus luctus fermentum. Duis consequat gravida ex, id pellentesque turpis finibus eu.
column-gap
.column-container {
column-count: 3;
column-gap: 2em;
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin rutrum nibh diam, et rhoncus nulla interdum vitae. Suspendisse ac quam justo. In ut enim faucibus, aliquet velit a, rhoncus mauris. Ut pharetra magna ac euismod gravida. Aenean fringilla ex sit amet est condimentum, fermentum dapibus diam finibus. Donec id tortor turpis. Morbi semper turpis quis posuere sagittis. Suspendisse ac pulvinar magna, a hendrerit arcu. Aenean dictum nunc sit amet libero fringilla, vel vulputate risus auctor. Vestibulum interdum vulputate nibh et sodales. Donec lorem nisi, mattis quis tempus sed, finibus at velit. Curabitur pharetra libero eget felis ornare finibus. Vivamus eget sollicitudin risus, eu lobortis est. Duis sed lectus a purus luctus fermentum. Duis consequat gravida ex, id pellentesque turpis finibus eu.
break-inside
.column-children {
break-inside: avoid;
}
The most basic and oldest layout method on the web.
<div>
has one default style, display: block
width
, height
margin
, padding
border
<strong>
, <em>
, <span>
)margin
and flex items❓margin
does not collapse inside of a flex container
.flex-item-3 {
margin-left: 2em;
margin-right: 2em;
}
.flex-item-4 { margin-left: 2em; }
box-sizing: content-box;
.element { /* Space taken up in layout */
padding: 5px 10px; /* 10px + 10px = 20px */
border-width: 2px; /* 20px + 2px + 2px = 24px */
width: 100px; /* 24px + 100px */
} /* Total 124px */
box-sizing: border-box;
.element { /* Space taken up in layout */
padding: 5px 10px; /* 10px + 10px = 20px */
border-width: 2px; /* 20px + 2px + 2px = 24px */
width: 100px; /* 100px */
} /* Total 100px */
.wrapper {
display: flex;
flex-wrap: wrap;
}
.half-column {
width: 50%;
border: 2px solid green;
padding: 0 15px;
}
border-box
saves the day!.wrapper {
display: flex;
flex-wrap: wrap;
}
.half-column {
box-sizing: border-box;
width: 50%;
border: 2px solid green;
padding: 0 15px;
}
BORDER BOX ALL THE THINGS!
* {
box-sizing: border-box;
}
position
Very useful, and often misused.
top, bottom, left, right
Change the location of "positioned" elements
z-index
Determines vertical layering of "positioned" elements
position: static;
Position's default value, these elements are not "positioned" so associated styles are ignored.
.element {
position: static;
top: 100px; /* Ignored, because position: static */
left: 50px; /* Static isn't considered "positioned" */
float: left;
}
position: relative;
Update the element from where it would rendered.
.element {
position: relative;
top: 25px;
left: 50px;
float: left;
}
position: absolute;
Update the element based on positioning of a "positioned" parent element
.element {
position: absolute;
top: 0;
left: 0;
float: left;
}
position: fixed;
Positions element to the window and element doesn't move when page scrolls.
.element {
position: fixed;
top: 100px;
left: 50px;
}
position: sticky;
Element will stick to defined position when page scrolls
(Not ready for prime time yet)
.element {
position: sticky;
top: 100px;
left: 50px;
}
position
position: absolute
.element {
position: absolute;
top: 0;
left: 0;
}
z-index
Some guidelines
Think in this order as a general rule:
Up Next: Transforms, Transitions & Animations
transform
transform: translate(x, y);
.element {
transform: translate(50px, 25px);
}
transform: translate(x);
.element {
transform: translate(50px);
}
transform: scale(x);
.element {
transform: scale(2);
}
transform: scale(x, y);
.element {
transform: scale(2, 0.5);
}
transform: rotate(deg);
.element {
transform: rotate(45deg);
}
transform: skew(deg, deg);
.element {
transform: skew(45deg, 15deg);
}
transform-origin: x, y;
.blue-element,
.red-element {
transform: rotate(45deg);
/* transform-origin: center center; Default */
}
.red-element {
transform-origin: left top;
}
Order matters!
.blue-element {
transform: translate(200px) rotate(45deg);
}
.red-element {
transform: rotate(45deg) translate(200px);
}
transition
.element {
transition: transform 1s;
}
.element:hover {
transform: translate(50px, 25px);
}
.element {
transition: transform 1s, background 3s;
}
.element:hover {
transform: translate(50px, 25px);
background: rgba(200, 0, 0, 0.6);
}
.blue-element { transition: transform 1s linear; }
.red-element { transition: transform 1s ease-in; }
.yellow-element { transition: transform 1s ease-out; }
.blue-element { transition-delay: 0; }
.red-element { transition-delay: 1s; }
.yellow-element { transition-delay: 2s; }
animation
@keyframes slide-in {
0% {
transform: translate(-15em);
opacity: 0;
}
100% {
transform: translate(0);
opacity: 1;
}
}
@keyframes slide-in { ... }
.element {
animation-name: slide-in;
animation-duration: 2s;
animation-iteration-count: infinite;
}
@keyframes slide-all-over {
0% {
transform: translate(-15em);
opacity: 0;
}
33% {
transform: translate(-10em, -5em);
}
66% {
transform: translate(-5em, 5em);
}
100% {
transform: translate(0);
opacity: 1;
}
}
If the desired animation can be done with transform, it should be.
cubic-bezier()
Make your own animation timing!
Now with web site helper!:before
and :after
(aka pseudo-content)
<span>
Bare minimum is a selector, before or after, and the content attribute (which can be an empty string).
.element:before {
content: '';
}
This creates an empty invisible element.
.clearfix:after {
content: '';
display: table;
clear: both;
}
So long as it isn't necessary for the content to be understood.
.email-address:before {
content: 'Contact me at ';
}
someone@something.com
[data-label]:before {
content: attr(data-label);
display: inline-block;
margin-right: 0.5em;
padding: 0.25em 0.5em;
background: rgb(225, 200, 0);
color: rgb(100, 50, 0);
}
@media print {
main a[href]:after {
content: " (" attr(href) ") ";
}
}
I stole this idea from CSS Tricks
There are a lot of tools, Web AIM contrast checker is an easy one.
:focus
selector when adding :hover
selector
.button:hover,
.button:focus {
background: #121399;
}
display: none;
visibility: hidden;
.element-invisible
.sr-only
text-indent: -9999em;
(and better mousing!)
Photo by Wade Austin Ellis on Unsplash
body.html.page-node-X
#header
#header-wrapper h2,
body.html.page-node-X
#header
#header-wrapper
#block-views-view-name-block-1
> .view-view-name
> .view-content
> .views-row
> .row-inner
> .views-field-title,
body.html.page-node-X
#header
#header-wrapper
#block-views-view-name-block-1
> .view-view-name
.attachment
.view-heading,
#block-views-view-name-block-1
> .view-view-name
.attachment
body.html.page-node-X
#header
#header-wrapper
.view-heading,
body.html.page-node-X
#header
#header-wrapper
#block-views-view-name-block-1
> .view-view-name
.attachment
.view-view-name
.views-row
.views-field-title,
#block-views-view-name-block-1
> .view-view-name
.attachment
.view-view-name
.views-row
body.html.page-node-X
#header
#header-wrapper
.views-field-title {
display: block;
text-align: center;
line-height: 1.3em;
padding-top: 140px
}
tagname
Type/Tag (0, 0, 1)
.class-name
Class (0, 1, 0)
#id-name
ID (1, 0, 0)
*
Universal (0, 0, 0)
[attribute]
Attribute (0, 1, 0)
<div attribute-name="value"><div>
[attribute-name] [attribute-name='value'] [attribute-name*='lu'] [attribute-name^='val']
All of these are a specificity of (0, 1, 0)
>
Direct descendant (0, 0, 0)
~
General sibling (0, 0, 0)
+
Adjacent Sibling (0, 0, 0)
:hover, :focus
(0, 1, 0)
:first-child, :last-child
(0, 1, 0)
:empty
(0, 1, 0)
:checked
(0, 1, 0)
:nth-child
Pseudo-Classes:nth-child()
(0, 1, 0)
:nth-of-type()
(0, 1, 0)
:nth-last-child()
(0, 1, 0)
.article h4 a
.main-menu > li a
.bio-photo ~ .bio-name
.js .carousel .slide
#main .article a
(1, 1, 1)
#page #main a
(2, 0, 1)
h4.sidebar-title a
(0, 1, 2)
#main .article a
(1, 1, 1)
.article a
(0, 1, 1)
#page #main a
(2, 0, 1)
[id="main"] a
(0, 1, 1)
h4.sidebar-title a
(0, 1, 2)
.sidebar-title a
(0, 1, 1)
<article class="node node-news node-published node-not-promoted node-not-sticky clearfix" id="node-news-2" about="/page-url" typeof="foaf:Document">
<div class="field field-name-body field-type-text-with-summary field-label-hidden">
<div class="field-items">
<div class="field-item even" property="content:encoded">
<p>Hello World!</p>
</div>
</div>
</div>
</article>
.node-news .field-name-bodyThan this:
.node .field
Explicit classes are meant to target very specific elements, e.g. .widget__photo--captioned
Utility classes are meant to apply very specific styles, e.g. .text-align-center
Consider prefixing utility classes, e.g. .u-text-align-center
e.g. Lullabot.com Example
lc-
for Lullabot.com) you know where it came from.sidebar .col-lg-3 {
text-align: right; /* .col-lg-3 is intended for layout, not text treatment :( */
}
!important
unless you're overriding inline styles.main-header .header-logo
header.main-header
.widget__title--featured
[id=”id-name”]
.my-widget[class][class]
nth-child
Tricks
Technically it does, but in the real world it's low value and high cost.
See:
Performance Impact of CSS Selectors - Steve stevesouders
@import
will-change
to clue in browser to animationsfont-display
to prevent a web font from blocking render