Pro-tip: Press space bar to progress and it won't skip any slides

Intermediate to Advanced CSS

For Practical Peoples

Wes Ruvalcaba

  • Senior Software Engineer at Red Hat
  • Writing CSS since 2002
  • Markup, CSS & Standards Dork
  • Tend to write custom code, more than repurpose existing

@wesruv

Feel free to ask questions at any time!

People I'm Stealing a lot from

  • Rachel Andrew
  • Chris Coyier
  • Jen Simmons
  • Mozilla Developer Network
  • ... and plenty of others (see sources slides)

The Goal

We'll go over

  • CSS "Units" and "Lengths"
  • Media Queries
  • Layout with CSS post Grid & Flexbox
  • Advanced styling techniques & animating
  • Accessibility
  • Debugging CSS Issues
  • Architecting CSS
  • Fancy Tips and Tricks

Foreword Advice

Prologue

Debugging Tool Basics

Sample page

Part 1

Units and Lengths

Units and Lengths

Pixels

1px
100px
.box {
  width: 60px;
  height: 60px;
  background: deepskyblue;
}
.box

1px !== 1 pixel on the screen

1px = 1 pixel * ScreenDensity

Screen pixel density usually ranges from:
1x, 1.25x, 1.5x, 2x, or 4x

Units and Lengths

Percentage

1%
33.333%
150%
.parent {
  border-color: gray;
  border-style: dashed;
}

.box {
  width: 50%;
  background: deepskyblue;
}
.box

Percentage ... of what?

Text Based Units

Units and Lengths

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
Units and Lengths
.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;
}
Units and Lengths

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
Units and Lengths

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:

.box
.box-2

Sans-Serif Font

Units and Lengths

Viewport Units

What's a viewport?

Viewport Area, the size of the browser
Units and Lengths

vw

vw - percentage width of the browser window
25vw
25vw examples
Units and Lengths

vh

vh - percantage height of the browser window
25vh
25vh examples
Units and Lengths

vmin

vmin - percantage of the smallest dimension (height or width)
25vmin
25vmin examples
Units and Lengths

vmax

vmin - percantage of the largest dimension (height or width)
25vmax
25vmax examples
Units and Lengths

Physical Units

  • mm millimeter
  • cm centimeter
  • in inch
  • pt point
  • pc pica
Units and Lengths

Which unit should I use?

Relative Units

When size should be proportionate to the unit's basis

Sized with em

My button Larger button

Sized with px

My button Larger button

Pixels

A fallback, if you can't/shouldn't use a relative unit.

Media Queries

Media Queries

Media Queries

Special styles for specific circumstances

@media /* Conditions */ {
  /* CSS Rules */
}

Which Medium?

@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.

What Size?

@media (min-width: 768px) {
  /* CSS Rules */
}

@media (min-width: 48em) and (min-height: 30em) {
  /* CSS Rules */
}

@media (max-height: 500px) {
  /* CSS Rules */
}
Media Queries

@media Best Practices

Mobile First @media queries

Write 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 */
  }
}

Group all styles for an element

/* Widget Styles */
.widget { }

@media (min-width: 768px) {
  .widget { }
}

/* Doo Dad Styles */
.doo-dad { }

@media (min-width: 768px) {
  .doo-dad { }
}

Only be as specific as necessary


@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 { }
}

Media queries should be based on content, not devices

  • Are columns squished?
  • Line lengths too long or short?
  • Images need to be bigger?

Devices can be a decent guide.
Test from 300px - 1600px wide.

Bootstrap.com between mobile and tablet has long line lengths making it harder to read

This screenshot is faked

Bootstrap.com faked example of when columns might be too constrained

CSS Layout post CSS Grid & Flexbox

Document Flow & You

Mock up of an article page
Mock up of an article page

Text Flow

  • How text behaves and tags like <strong> & <em>
  • Inline* elements mimic text flow
  • White space matters* (*up to one space!)

Layout Flow

  • White space agnostic
  • Properties like:
    • Grid
    • Flexbox
    • Table
    • Columns
Mock up of an article page
Mock up of an article page

Document Flow Breakers:

Document Flow

position: absolute, fixed, sticky

Mess with Document Flow

  • position: relative
    (when top, right, bottom or left are set)
  • transform
  • negative margin or padding
Mock up of an article page

TL:Didn't think your cartoons were funny

  • Breaking the flow can cause complicated, hard to solve problems.
  • Try to use Flow-friendly tools first.
  • If you enjoy sanity, the large majority of the elements on the page should be flow-friendly.

Layout 101 in Post-CSS Grid

Floats

Don't use them for layout anymore*!

* Except for fallbacks or if you know better options aren't wise
based on your user stats.

Document flow cartoon character

Are floats still good for something?

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.

Terminology

CSS Grid

Basics and terminology

CSS Grid

Great at 2 dimensional, custom, and large scale layouts

  • Define amount of rows and columns
  • Define constraints for rows and columns
  • Constraints can be rigid, flexible, or content based

Grid Container

Element surrounding the grid.

Grid Item

Direct child element of a grid container

Grid Item
Grid Item
Grid Item

Grid Line

Any line in the grid


← Grid Lines →

Beginning with Grid

Basic syntax

.grid-container {
  display: grid;
  grid-template-columns: 25% 50% 25%;
}

What if there's more content than grid areas?

Let's see in this example...

Grid code examples stolen/modified from GridByExample.com, from Rachel Andrew

Specifically placing a grid-item:


  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 2;

Specifically placing a grid-item from the end!


  grid-column-start: -3;
  grid-column-end: -1;
  grid-row-start: -2;
  grid-row-end: -1;

  grid-column-start: 1;
  grid-column-end: -1;

Break!
Be back at

Try to complete as many as you can on our break
(try at least 5):

CSSGridGarden.com

More CSS Grid

Grid Item Shorthand

.my-header {
  grid-column: 1 / -1;
}

.my-content {
  grid-column: 1 / span 2;
}

.my-sidebar {
  grid-row: 2;
  grid-column: 3;
}
Header
grid-column: 1 / -1
Content
grid-column: 1 / span 2
Sidebar
grid-row: 2;
grid-column: 3;

Named grid areas

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; }
Content
Header
Sidebar
Footer
.grid-container {
  display: grid;
  grid-template-columns: 50% 50%;
  grid-template-areas:
    'header header'
    'content content'
    'sidebar footer';
}
Content
Header
Sidebar
Footer

Grid Units & Helpers

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;

Example

repeat(number, size)

display: grid;
grid-gap: 10px;
grid-template-columns: repeat(4, 100px);
grid-template-rows: repeat(3, auto);

Example

auto-fit and auto-fill

grid-template-columns: repeat(auto-fit, 150px)
Will make columns fit available space.
grid-template-columns: repeat(auto-fill, 150px)
Will add columns as it has room for more.

Example

Masonry like layout

display: grid;
grid-template-columns:
  repeat(auto-fit, minmax(180px, 1fr));
grid-gap: 1rem;

Example

Can I use Grid Now?

CanIUse.com, Globally 93.29% fully support Grid
Access.Redhat.com
94%
fully support Grid A client whose a group of scientists, about 87% will get grid
Site for network of scientists (as of 10/2019)
83%
fully support Grid A client whose a group of scientists, about 87% will get grid
Carnegie Mellon School of Computer Science (as of 10/2019)
96%
fully support Grid
Lullabot.com (as of 10/2019)
99%
fully support Grid Lullabot.com, About 98% of visitors will get Grid layout (1/7/2018)

CSS Grid Tips

@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';
  }
}

Want equal width columns with gutter?

You'd think...

.wrapper {
  display: grid;
  grid-template-columns: 25% 25% 25% 25%;
  grid-gap: 10px;
}

But look at what that gives you...

How to get equal width columns with gutter

.wrapper {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-gap: 10px;
}

Take a look...

Break!
Be back at

Fix the equal width grid with gutters yourself:
codepen.io/pen/RvBzrV

Try more CSSGridGarden.com

Or explore GridByExample.com

Terminology

Flexbox

Basics and terminology

Flexbox

Best at 1 dimensional and small scale layouts.

  • Can direct flow of content, horizontal/vertical, reverse/regular direction
  • Can distribute extra space many ways
  • Can change displayed order of items
  • Can handle multiple rows/columns, but with less control than CSS Grid

Flex Container

Element enclosing everything

Flex Item

Direct child of flex container

Main Axis

The axis the flex items are laid out on (row/column).

← Main Axis →

Cross Axis

The opposite axis of the main (column/row)

← Cross
Axis →

Main Start & End

The beginning of the main axis is where items start from, end is the opposite side.

← Main Start
Main End →

Cross Start & End

The beginning of the cross axis will be top if flex is horizontal, left if it's vertical

Cross Start
Cross End

Beginning with Flex Box

Basic syntax

.flex-container {
  display: flex; /* All you need */
  /* flex-direction: row; (Default) */
  /* flex-wrap: nowrap;   (Default) */
}

Behold, the not wrapping!

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;
}

Other justify-content values

justify-content: flex-start;
justify-content: flex-end;

Other justify-content values

justify-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;
}
1
Second item
I think this one is number 3
4

Other align-items values

align-items: stretch; /* (Default) */
1
Second item
I think this one is number 3
4
align-items: flex-start;
1
Second item
I think this one is number 3
4
align-items: flex-end;
1
Second item
I think this one is number 3
4

Other align-items values

align-items: center;
1
Second item
I think this one is number 3
4
align-items: baseline;
1
Second item
I think this one is number 3
4

Break!
Be back at

Try to complete as many as you can on our break
(try to get to exercise 10):

FlexboxFroggy.com

Hint: Having "A Complete Guide to Flexbox" from CSS-Tricks.com open in another browser may come in handy!

More Flexbox

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;
}
1
2
3
4
5

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 */ }
1
2
3
4
5

flex-basis

Sets initial size of flex item

.flex-item-3 { flex-basis: 4em; }
.flex-item-4 { flex-basis: 2em; }
1
2
3
4
5

flex-grow

Distributes extra space to items that have a value

.flex-item-3 { flex-grow: 2; }
.flex-item-4 { flex-grow: 1; }
1
2
3
4
5

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; }
1
2
3
4
5
6
7
8

💖margin and flex items💖

auto will use left over space to push as far as it can

.flex-item-3 {
  margin: auto;
}
1
2
3
4
5

Can I use Flexbox Now?

CanIUse.com screenshot

Break!
Be back at

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!

CSS Columns

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.

Basic syntax

.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.

Or Specify 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;
}
  • 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.

CSS Column Gotcha

Beware effects that render at the bottom of columns.

Block Layout & Box Model

Block Layout

The most basic and oldest layout method on the web.

  • A <div> has one default style, display: block
  • Block elements gets stacked on top of each other
  • Block elements default to 100% width
  • Works well with all the box model properties:
    • width, height
    • margin, padding
    • border

When should I use block layout?

  • Nothing cooler makes sense
  • You want to use box model properties
  • The element shouldn't be inline with text
    (unlike <strong>, <em>, <span>)

Box Model

This is content
Depiction of box-model from chrome
Cat
Cat
Cat
Cat
Cat
Cat
Cat Cat
Let's play...

Describe that Cat with Box Model!

Cat
Cat
Cat Cat
Cat Cat

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; }
1
2
3
4
5

Box Sizing

How the browser measures width and height.

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 */

Where it goes wrong

.wrapper {
  display: flex;
  flex-wrap: wrap;
}

.half-column {
  width: 50%;
  border: 2px solid green;
  padding: 0 15px;
}
Column 1
Column 2

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;
}
Column 1
Column 2

Editorial:

BORDER BOX ALL THE THINGS!

* {
  box-sizing: border-box;
}

position

Very useful, and often misused.

Position's Associated Styles

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.

This is some example text
.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.

This is some example text
.element {
  position: relative;
  top: 25px;
  left: 50px;
  float: left;
}

position: absolute;

Update the element based on positioning of a "positioned" parent element

This is some example text
.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;
}

How & When to Use position

Scoping position: absolute
This is some example text
.element {
  position: absolute;
  top: 0;
  left: 0;
}
Overlayed caption
Tiny text on a phone
This is my cool caption
Lorem ipsum dolor sit amet, floating that ramble jab all zaszzy like.

Scoping z-index

How do I know which layout method to use?

Some guidelines

Start Outside In

Flow Friendly First

Think in this order as a general rule:

  • Grid
  • Flex box
  • Box model
  • Position

Remember what layout methods are best at

  • Grid - 2d layout
  • Flex box - 1d layout
  • Box model - Sets up simple box-model properties
  • Position - Great special cases, can be risky

When an element isn't cooperating...

  • Check the layout properties of the element and it's parent
  • Are we using the best tool?
  • To the Google!
  • Is it better to rework the design?

Break!
Be back at

Up Next: Transforms, Transitions & Animations

Transforms, Transitions & Animations

transform

  • Manipulates elements visually
  • Can move, scale, rotate, and more
  • Anti-aliases content
  • Messes with document flow, but doesn't break it
  • Smoothest and most performant way to animate elements
  • Can define multiple transforms

transform: translate(x, y);

.element {
  transform: translate(50px, 25px);
}
This is some example text

transform: translate(x);

.element {
  transform: translate(50px);
}
This is some example text

transform: scale(x);

.element {
  transform: scale(2);
}
This is some example text

transform: scale(x, y);

.element {
  transform: scale(2, 0.5);
}
This is some example text

transform: rotate(deg);

.element {
  transform: rotate(45deg);
}
This is some example text

transform: skew(deg, deg);

.element {
  transform: skew(45deg, 15deg);
}
This is some example text

transform-origin: x, y;

.blue-element,
.red-element {
  transform: rotate(45deg);
  /* transform-origin: center center; Default */
}
.red-element {
  transform-origin: left top;
}
This is some example text
Scale set at 0.75
Skew at 45deg
Translate at 100px

Multiple transforms

Order matters!

.blue-element {
  transform: translate(200px) rotate(45deg);
}
.red-element {
  transform: rotate(45deg) translate(200px);
}

Transform Pro-Tips

  • Elements with small detail might appear 'fuzzy' after being transformed
  • Using 3D transform will use graphics hardware acceleration, which can waste a phone's battery faster
  • 3D transforms can cause laggy or slow performance on phones or less powerful devices

transition

  • Used to transition from current state to new state
  • Can be used on any 'animeatable' property
  • Can transition multiple properties
.element {
  transition: transform 1s;
}
.element:hover {
  transform: translate(50px, 25px);
}
This is some example text
.element {
  transition: transform 1s, background 3s;
}
.element:hover {
  transform: translate(50px, 25px);
  background: rgba(200, 0, 0, 0.6);
}
This is some example text

Timing Functions

linear, ease, ease-in, ease-out, ease-in-out Image from: Jotform - How to Use CSS Animations Like a Pro
.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

  • Animates between multiple configurations
  • Can loop a number of times, or infinitely
  • Doesn't require user interaction, but can be based on interactions
  • Can animate any 'animeatable' property

Definining Keyframes

@keyframes slide-in {
  0% {
    transform: translate(-15em);
    opacity: 0;
  }
  100% {
    transform: translate(0);
    opacity: 1;
  }
}

Apply the animation

@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;
  }
}

Animation Pro-Tips

Transforms are the awesome

If the desired animation can be done with transform, it should be.

  • Performs better
  • Won't effect layout
  • Animation will be smoother because of anti-aliasing

Live example of transform > other styles for animation

Don't move something that animates on hover

This is some example text

Animation Accessibility concerns

cubic-bezier()

Make your own animation timing!

Now with web site helper!

:before and :after

(aka pseudo-content)

  • Adds new elements to the inside of the selected element, essentially a free <span>
  • 2 of these can be placed on any element with a closing tag
  • Can insert text into the page, but it is very spotty in accessibility tools

Creating Pseudo-Content

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 uses an empty invisible after element

.clearfix:after {
  content: '';
  display: table;
  clear: both;
}

Can add supplemental content

So long as it isn't necessary for the content to be understood.

.email-address:before {
  content: 'Contact me at ';
}

Can expose html attributes

[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);
}
Cool thing!

Can show URLs of links in the print stylesheet

@media print {
  main a[href]:after {
    content: " (" attr(href) ") ";
  }
}
I stole this idea from CSS Tricks

CSS Accessibility Concerns

Color contrast and Font-size

This isn't very legible
This isn't very legible

There are a lot of tools, Web AIM contrast checker is an easy one.

Add :focus selector when adding :hover selector

.button:hover,
.button:focus {
  background: #121399;
}

Content hiding options!

  • Hide from everyone!
    display: none; visibility: hidden;
  • Hide from sighted users
    CSS clipping, like .element-invisible .sr-only text-indent: -9999em;
Andre the Giant's giant meaty man mitts were 10 inches from palm to finger tips, average male hand is 7 inches. Andrew could use an ipad as an iphone pretty comfortablly.

Make hit areas 45x45 for touch

(and better mousing!)

Break!
Be back at

Coming up: Setting up projects to avoid CSS related headaches

  • Specificity
  • Selectors
  • Architecting Your CSS

Setting up projects to avoid CSS related headaches

A tale of two project's CSS

Photo by Wade Austin Ellis on Unsplash

0, 7, 0
Specificity chart for lullabot.com, showing it's quite low
3, 7, 1
Specificity chart for futurist technology web site, showing it's specificity is out of control
Specificity chart for lullabot.com, showing it's quite low
Specificity chart for futurist technology web site, showing it's specificity is out of control
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
}

CSS Selectors & Specificity

Simple Selectors

  • 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)

MDN Attribute Selectors Documentation

Attribute Selector

<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)

MDN Attribute Selectors Documentation

Combinators

  • > Direct descendant (0, 0, 0)
  • ~ General sibling (0, 0, 0)
  • + Adjacent Sibling (0, 0, 0)

MDN CSS Combinators Documentation

Pseudo-Classes

  • :hover, :focus (0, 1, 0)
  • :first-child, :last-child (0, 1, 0)
  • :empty (0, 1, 0)
  • :checked (0, 1, 0)

MDN Pseudo Classes Documentation

:nth-child Pseudo-Classes

  • :nth-child() (0, 1, 0)
  • :nth-of-type() (0, 1, 0)
  • :nth-last-child() (0, 1, 0)

How to read selectors

Read back to front

.article h4 a
.main-menu > li a
.bio-photo ~ .bio-name
.js .carousel .slide

Choosing the best selector for the job

  1. Keep Specificity Low
  2. Only target what you mean to
  3. Try to use selectors that explain what they're targeting

Keep Specificity Low

Too Loud!
  • #main .article a (1, 1, 1)
  • #page #main a (2, 0, 1)
  • h4.sidebar-title a (0, 1, 2)
Much Better!
  • #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)

Only target what you mean to

<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>

Try to use selectors that explain what they're targeting

When possible create descriptive and specific class names
This is much more descriptive:
.node-news .field-name-body
Than this:
.node .field

CSS Architecture Best Practices

The larger the project, the more important CSS standards & architecture are.

Starting from scratch

  • Use normalize.css, or reset.css, or similar
  • Decide on a class naming convention

Think about explicit vs utility classes

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

Document all of these decisions in a README

e.g. Lullabot.com Example

Working inside of a framework

  • Consider using a prefix for custom classes especially if the framework does not (e.g. lc- for Lullabot.com) you know where it came from
  • Don’t write selectors that use framework utility classes unless you’re extending them, e.g.
    .sidebar .col-lg-3 {
      text-align: right; /* .col-lg-3 is intended for layout, not text treatment :( */
    }

Guidelines for framework or contrib vs custom code uses

  • Using just the grid? Grid + some components?
  • Prefer or avoid using framework components?

On Selectors

  • Use classes, not id's or tags (except for base tag styling)
  • Write styles so the cascade starts at the most general, to the most specific. Some good examples are SMACSS or Inverted Pyramid
  • Avoid inline styles as much as possible (in markup or javascript)
  • Don't use !important unless you're overriding inline styles

Only be as specific as necessary

  • Avoid unneccessary parts of your selector, e.g. .main-header .header-logo
  • Don’t 'qualify' classes by adding the tag name e.g. header.main-header
  • Avoid compound selectors by creating highly specific class names; e.g. BEM class naming .widget__title--featured
  • If you're using Drupal or a CSS Preprocessor, break up your CSS into small organized files
  • Use auto-prefixer, in a build step, as a plugin for your editor, or use Autoprefixer.github.io
  • If id is the best styling hook, use [id=”id-name”]
  • If specificity is too low, but adding other class names would be bloat, use an attribute selector like .my-widget[class][class]

Fancy nth-child Tricks

Page Performance & CSS

CSS Selector speed doesn't matter

In IE7 morme CSS selectors have low effect on page speed until 18,000

Technically it does, but in the real world it's low value and high cost.
See: Performance Impact of CSS Selectors - Steve stevesouders

Things to avoid:

  • @import
  • Base64 assets

Tips:

  • Inline critical CSS
  • Manage filesize with minification
  • Use will-change to clue in browser to animations
  • Use font-display to prevent a web font from blocking render

For animation or manipulation:

  • Transforms for animations whenever possible
  • Don't use 3d transforms (typically used for parallax)
  • Don't cause reflow when possible

Debugging tips and tricks

Sources