CSS Advanced (Part 1)

Master advanced CSS concepts including CSS architecture, preprocessors, custom properties, and advanced selectors.

CSS Advanced Content

This content has been divided into two parts for better readability:

CSS Architecture

CSS architecture refers to the organization of your CSS code. A well-structured CSS architecture makes your code more maintainable, scalable, and easier to understand.

Common CSS Architecture Methodologies

BEM (Block, Element, Modifier)

BEM is a naming convention that makes your CSS more readable and understandable, while also solving issues with specificity.

/* Block component */
.card {
    background-color: white;
    border-radius: 4px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* Element that depends upon the block */
.card__title {
    font-size: 1.5rem;
    margin-bottom: 0.5rem;
}

.card__image {
    width: 100%;
    height: auto;
}

.card__content {
    padding: 1rem;
}

/* Modifier that changes the style of the block */
.card--featured {
    border-left: 5px solid gold;
}

.card--dark {
    background-color: #333;
    color: white;
}

HTML implementation:

<div class="card card--featured">
    <img class="card__image" src="image.jpg" alt="Card image">
    <div class="card__content">
        <h2 class="card__title">Card Title</h2>
        <p class="card__text">Card content goes here...</p>
    </div>
</div>

SMACSS (Scalable and Modular Architecture for CSS)

SMACSS categorizes CSS rules into five types: Base, Layout, Module, State, and Theme.

/* Base rules */
body, h1, h2, p, ul, li {
    margin: 0;
    padding: 0;
}

a {
    text-decoration: none;
    color: #0066cc;
}

/* Layout rules */
.l-header {
    width: 100%;
    position: sticky;
    top: 0;
    z-index: 100;
}

.l-sidebar {
    width: 25%;
    float: left;
}

.l-main {
    width: 75%;
    float: right;
}

/* Module rules */
.nav {
    background-color: #333;
}

.nav-item {
    display: inline-block;
    padding: 10px 15px;
}

/* State rules */
.is-active {
    font-weight: bold;
    color: #fff;
}

.is-hidden {
    display: none;
}

/* Theme rules */
.theme-dark {
    background-color: #333;
    color: #fff;
}

.theme-light {
    background-color: #fff;
    color: #333;
}

OOCSS (Object-Oriented CSS)

OOCSS focuses on separating structure from skin and container from content.

/* Structure */
.btn {
    display: inline-block;
    padding: 0.5em 1em;
    border-radius: 4px;
    cursor: pointer;
}

/* Skin */
.btn-primary {
    background-color: #0066cc;
    color: white;
    border: 1px solid #0055aa;
}

.btn-secondary {
    background-color: #f0f0f0;
    color: #333;
    border: 1px solid #ddd;
}

/* Usage */
/* <button class="btn btn-primary">Primary Button</button> */
/* <button class="btn btn-secondary">Secondary Button</button> */

Atomic CSS

Atomic CSS (also known as Functional CSS) uses small, single-purpose classes that are named based on their visual function.

/* Atomic classes */
.m-0 { margin: 0; }
.mt-1 { margin-top: 0.25rem; }
.mb-2 { margin-bottom: 0.5rem; }
.p-3 { padding: 1rem; }
.text-center { text-align: center; }
.flex { display: flex; }
.items-center { align-items: center; }
.bg-blue { background-color: blue; }
.text-white { color: white; }
.rounded { border-radius: 0.25rem; }

/* Usage */
/* <div class="flex items-center p-3 bg-blue text-white rounded">
     <h2 class="m-0">Title</h2>
     <p class="mt-1 mb-2">Content</p>
   </div> */

CSS File Organization

Organizing your CSS files is crucial for maintainability. Here's a common approach:

styles/
├── main.css             # Main CSS file that imports all others
├── base/
│   ├── _reset.css       # CSS reset or normalize
│   ├── _typography.css  # Typography rules
│   └── _variables.css   # CSS variables
├── layout/
│   ├── _grid.css        # Grid system
│   ├── _header.css      # Header styles
│   └── _footer.css      # Footer styles
├── components/
│   ├── _buttons.css     # Button styles
│   ├── _cards.css       # Card styles
│   └── _forms.css       # Form styles
├── pages/
│   ├── _home.css        # Home page specific styles
│   └── _about.css       # About page specific styles
└── utils/
    ├── _helpers.css     # Helper classes
    └── _mixins.css      # Mixins (for preprocessors)

CSS Namespacing

Namespacing helps to avoid conflicts and provides context for your CSS classes.

/* Component namespace */
.c-button { /* Component */ }
.c-card { /* Component */ }

/* Utility namespace */
.u-hidden { /* Utility */ }
.u-text-center { /* Utility */ }

/* State namespace */
.is-active { /* State */ }
.has-error { /* State */ }

/* JavaScript namespace */
.js-modal-trigger { /* JavaScript hook */ }
.js-form-submit { /* JavaScript hook */ }

CSS Architecture Best Practices

CSS Preprocessors

CSS preprocessors extend CSS with features like variables, nesting, mixins, and functions. They help you write more maintainable and reusable CSS code.

Popular CSS Preprocessors

Sass Features

Sass (Syntactically Awesome Style Sheets) is one of the most popular CSS preprocessors. It comes in two syntaxes: SCSS (Sassy CSS) and the indented syntax (Sass).

Variables

// SCSS Syntax
$primary-color: #0066cc;
$secondary-color: #f0f0f0;
$font-stack: 'Helvetica', 'Arial', sans-serif;
$base-font-size: 16px;
$spacing-unit: 8px;

body {
    font-family: $font-stack;
    font-size: $base-font-size;
    color: $primary-color;
}

.button {
    background-color: $primary-color;
    padding: $spacing-unit * 2;
    margin-bottom: $spacing-unit * 3;
}

Nesting

// SCSS Syntax
.card {
    background-color: white;
    border-radius: 4px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    
    &__header {
        padding: $spacing-unit * 2;
        border-bottom: 1px solid $secondary-color;
        
        h2 {
            margin: 0;
            font-size: 1.5rem;
        }
    }
    
    &__body {
        padding: $spacing-unit * 2;
    }
    
    &__footer {
        padding: $spacing-unit * 2;
        border-top: 1px solid $secondary-color;
    }
    
    // Modifier
    &--featured {
        border-left: 5px solid gold;
    }
}

Mixins

// SCSS Syntax
@mixin flex-center {
    display: flex;
    align-items: center;
    justify-content: center;
}

@mixin truncate-text {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

@mixin responsive-font($min-size, $max-size, $min-width, $max-width) {
    font-size: $min-size;
    
    @media (min-width: $min-width) {
        font-size: calc(#{$min-size} + #{strip-unit($max-size - $min-size)} * ((100vw - #{$min-width}) / #{strip-unit($max-width - $min-width)}));
    }
    
    @media (min-width: $max-width) {
        font-size: $max-size;
    }
}

// Usage
.hero {
    @include flex-center;
    height: 100vh;
    
    &__title {
        @include responsive-font(2rem, 4rem, 320px, 1200px);
    }
    
    &__subtitle {
        @include truncate-text;
        max-width: 300px;
    }
}

Functions

// SCSS Syntax
@function strip-unit($number) {
    @if type-of($number) == 'number' and not unitless($number) {
        @return $number / ($number * 0 + 1);
    }
    @return $number;
}

@function rem($pixels, $context: 16) {
    @return ($pixels / $context) * 1rem;
}

@function color-contrast($color) {
    $r: red($color);
    $g: green($color);
    $b: blue($color);
    $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
    
    @return if($yiq >= 128, #000, #fff);
}

// Usage
.button {
    font-size: rem(16);
    padding: rem(12) rem(24);
    background-color: $primary-color;
    color: color-contrast($primary-color);
}

Partials and Imports

// _variables.scss
$primary-color: #0066cc;
$secondary-color: #f0f0f0;

// _mixins.scss
@mixin flex-center {
    display: flex;
    align-items: center;
    justify-content: center;
}

// main.scss
@import 'variables';
@import 'mixins';

body {
    color: $primary-color;
    background-color: $secondary-color;
}

.container {
    @include flex-center;
}

Control Directives

// SCSS Syntax
$theme: 'dark';

// If statement
@if $theme == 'dark' {
    body {
        background-color: #333;
        color: #fff;
    }
} @else {
    body {
        background-color: #fff;
        color: #333;
    }
}

// For loop
@for $i from 1 through 5 {
    .col-#{$i} {
        width: 20% * $i;
    }
}

// Each loop
$sizes: (small: 0.5rem, medium: 1rem, large: 2rem);

@each $name, $size in $sizes {
    .margin-#{$name} {
        margin: $size;
    }
    
    .padding-#{$name} {
        padding: $size;
    }
}

// While loop
$i: 1;
@while $i <= 5 {
    .item-#{$i} {
        width: 100% / $i;
    }
    $i: $i + 1;
}

PostCSS

PostCSS is a tool for transforming CSS with JavaScript plugins. It can be used to add modern CSS features, automate routine tasks, and more.

/* Before PostCSS processing */
.example {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 20px;
    color: color(#0066cc alpha(80%));
    user-select: none;
}

/* After PostCSS processing with autoprefixer, postcss-color-function, etc. */
.example {
    display: -ms-grid;
    display: grid;
    -ms-grid-columns: (minmax(250px, 1fr))[auto-fill];
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 20px;
    color: rgba(0, 102, 204, 0.8);
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
}

Popular PostCSS Plugins

Setting Up a CSS Preprocessor

Here's a basic setup for using Sass with npm:

// Install Sass
npm install sass --save-dev

// Add script to package.json
{
    "scripts": {
        "sass": "sass src/scss:dist/css --watch"
    }
}

// Run Sass compiler
npm run sass

And here's a basic setup for PostCSS:

// Install PostCSS and plugins
npm install postcss postcss-cli autoprefixer postcss-preset-env cssnano --save-dev

// Create postcss.config.js
module.exports = {
    plugins: [
        require('autoprefixer'),
        require('postcss-preset-env')({ stage: 1 }),
        require('cssnano')({ preset: 'default' })
    ]
}

// Add script to package.json
{
    "scripts": {
        "postcss": "postcss src/css/*.css --dir dist/css --watch"
    }
}

// Run PostCSS
npm run postcss

CSS Custom Properties (Variables)

CSS custom properties (also known as CSS variables) allow you to store values that you can reuse throughout your stylesheet.

Declaring and Using Custom Properties

/* Declaring custom properties */
:root {
    --primary-color: #0066cc;
    --secondary-color: #f0f0f0;
    --font-family: 'Helvetica', 'Arial', sans-serif;
    --base-font-size: 16px;
    --spacing-unit: 8px;
    --border-radius: 4px;
    --transition-duration: 0.3s;
}

/* Using custom properties */
body {
    font-family: var(--font-family);
    font-size: var(--base-font-size);
    line-height: 1.5;
    color: #333;
}

.button {
    background-color: var(--primary-color);
    color: white;
    padding: calc(var(--spacing-unit) * 2) calc(var(--spacing-unit) * 4);
    border-radius: var(--border-radius);
    transition: background-color var(--transition-duration) ease;
}

.button:hover {
    background-color: color-mix(in srgb, var(--primary-color) 80%, black);
}

Scoping Custom Properties

Custom properties can be scoped to specific elements, allowing you to create component-specific variables or override global variables.

/* Global variables */
:root {
    --text-color: #333;
    --background-color: white;
}

/* Light theme (default) */
body {
    color: var(--text-color);
    background-color: var(--background-color);
}

/* Dark theme */
.theme-dark {
    --text-color: white;
    --background-color: #333;
}

/* Component-specific variables */
.card {
    --card-padding: 16px;
    --card-border-color: #ddd;
    
    padding: var(--card-padding);
    border: 1px solid var(--card-border-color);
    border-radius: var(--border-radius);
}

.card--compact {
    --card-padding: 8px;
}

Fallback Values

You can provide fallback values for custom properties in case they are not defined or supported.

/* Using fallback values */
.element {
    /* If --brand-color is not defined, use #0066cc */
    color: var(--brand-color, #0066cc);
    
    /* Nested fallbacks */
    padding: var(--element-padding, var(--global-padding, 16px));
}

Manipulating Custom Properties with JavaScript

One of the advantages of custom properties is that they can be manipulated with JavaScript.

// Get a custom property value
const rootStyles = getComputedStyle(document.documentElement);
const primaryColor = rootStyles.getPropertyValue('--primary-color').trim();
console.log('Primary color:', primaryColor);

// Set a custom property value
document.documentElement.style.setProperty('--primary-color', '#ff0000');

// Change theme based on user preference
const themeToggle = document.getElementById('theme-toggle');
themeToggle.addEventListener('change', function() {
    if (this.checked) {
        document.documentElement.style.setProperty('--text-color', 'white');
        document.documentElement.style.setProperty('--background-color', '#333');
    } else {
        document.documentElement.style.setProperty('--text-color', '#333');
        document.documentElement.style.setProperty('--background-color', 'white');
    }
});

Responsive Design with Custom Properties

Custom properties can be particularly useful for responsive design, allowing you to change values at different breakpoints.

/* Base variables */
:root {
    --container-width: 100%;
    --heading-font-size: 24px;
    --content-padding: 16px;
}

/* Tablet breakpoint */
@media (min-width: 768px) {
    :root {
        --container-width: 750px;
        --heading-font-size: 32px;
        --content-padding: 24px;
    }
}

/* Desktop breakpoint */
@media (min-width: 1024px) {
    :root {
        --container-width: 980px;
        --heading-font-size: 40px;
        --content-padding: 32px;
    }
}

/* Using the variables */
.container {
    width: var(--container-width);
    margin: 0 auto;
    padding: 0 var(--content-padding);
}

h1 {
    font-size: var(--heading-font-size);
}

Theming with Custom Properties

Custom properties are excellent for implementing theme systems.

/* Base theme variables */
:root {
    /* Colors */
    --color-primary: #0066cc;
    --color-secondary: #f0f0f0;
    --color-accent: #ff6b6b;
    --color-text: #333;
    --color-text-light: #666;
    --color-background: white;
    --color-border: #ddd;
    
    /* Typography */
    --font-family-base: 'Helvetica', 'Arial', sans-serif;
    --font-family-heading: 'Georgia', serif;
    --font-size-base: 16px;
    --line-height-base: 1.5;
    
    /* Spacing */
    --spacing-unit: 8px;
    --spacing-xs: calc(var(--spacing-unit) * 0.5);
    --spacing-sm: var(--spacing-unit);
    --spacing-md: calc(var(--spacing-unit) * 2);
    --spacing-lg: calc(var(--spacing-unit) * 3);
    --spacing-xl: calc(var(--spacing-unit) * 4);
    
    /* Borders */
    --border-radius-sm: 2px;
    --border-radius-md: 4px;
    --border-radius-lg: 8px;
    --border-width: 1px;
    
    /* Shadows */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
    --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
    
    /* Transitions */
    --transition-duration-fast: 0.15s;
    --transition-duration-normal: 0.3s;
    --transition-duration-slow: 0.5s;
    --transition-timing-function: ease;
}

/* Dark theme */
.theme-dark {
    --color-primary: #4d9fff;
    --color-secondary: #333;
    --color-accent: #ff8f8f;
    --color-text: #f0f0f0;
    --color-text-light: #aaa;
    --color-background: #222;
    --color-border: #444;
    
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.3);
}

/* High contrast theme */
.theme-high-contrast {
    --color-primary: #0000ff;
    --color-secondary: #000;
    --color-accent: #ff0000;
    --color-text: #000;
    --color-text-light: #333;
    --color-background: #fff;
    --color-border: #000;
    
    --border-width: 2px;
}

Advanced Techniques with Custom Properties

Calculated Values

:root {
    --base-size: 16px;
    --scale-ratio: 1.25;
    
    --size-xs: calc(var(--base-size) / var(--scale-ratio));
    --size-sm: var(--base-size);
    --size-md: calc(var(--base-size) * var(--scale-ratio));
    --size-lg: calc(var(--size-md) * var(--scale-ratio));
    --size-xl: calc(var(--size-lg) * var(--scale-ratio));
}

h1 { font-size: var(--size-xl); }
h2 { font-size: var(--size-lg); }
h3 { font-size: var(--size-md); }
p { font-size: var(--size-sm); }
small { font-size: var(--size-xs); }

Custom Property Toggles

/* Using custom properties as toggles */
.accordion {
    --is-open: 0;
}

.accordion.is-open {
    --is-open: 1;
}

.accordion__content {
    max-height: calc(var(--is-open) * 500px);
    opacity: var(--is-open);
    overflow: hidden;
    transition: max-height 0.3s ease, opacity 0.3s ease;
}

Advanced CSS Selectors

CSS provides a wide range of selectors that allow you to target elements with great precision.

Attribute Selectors

Attribute selectors allow you to select elements based on their attributes and attribute values.

/* Elements with a specific attribute */
[data-role] {
    /* Targets any element with a data-role attribute */
}

/* Elements with a specific attribute value */
[data-role="button"] {
    /* Targets elements with data-role="button" */
}

/* Elements with an attribute value that starts with a specific string */
[href^="https://"] {
    /* Targets links that start with https:// */
}

/* Elements with an attribute value that ends with a specific string */
[href$=".pdf"] {
    /* Targets links to PDF files */
}

/* Elements with an attribute value that contains a specific string */
[href*="example"] {
    /* Targets links that contain "example" in the URL */
}

/* Elements with an attribute value that contains a specific word */
[class~="card"] {
    /* Targets elements with a class that includes the word "card" */
}

/* Elements with a hyphen-separated attribute value starting with a specific string */
[lang|="en"] {
    /* Targets elements with lang="en" or lang="en-US", etc. */
}

Pseudo-Classes

Pseudo-classes select elements based on their state or position.

/* User action pseudo-classes */
a:hover { /* When the user hovers over a link */ }
a:active { /* When the user activates a link (e.g., clicks it) */ }
a:focus { /* When the link has focus (e.g., tabbed to) */ }
a:visited { /* When the link has been visited */ }

/* Form state pseudo-classes */
input:focus { /* When the input has focus */ }
input:disabled { /* When the input is disabled */ }
input:enabled { /* When the input is enabled */ }
input:checked { /* When the checkbox or radio button is checked */ }
input:required { /* When the input is required */ }
input:optional { /* When the input is optional */ }
input:valid { /* When the input is valid */ }
input:invalid { /* When the input is invalid */ }
input:in-range { /* When the input value is within the specified range */ }
input:out-of-range { /* When the input value is outside the specified range */ }
input:placeholder-shown { /* When the input is showing a placeholder */ }

/* Structural pseudo-classes */
li:first-child { /* The first child element */ }
li:last-child { /* The last child element */ }
li:nth-child(2) { /* The second child element */ }
li:nth-child(odd) { /* Odd-numbered child elements (1, 3, 5, etc.) */ }
li:nth-child(even) { /* Even-numbered child elements (2, 4, 6, etc.) */ }
li:nth-child(3n+1) { /* Every 3rd element, starting from the 1st */ }
li:nth-last-child(2) { /* The second-to-last child element */ }
li:only-child { /* Elements that are the only child of their parent */ }
p:first-of-type { /* The first element of its type */ }
p:last-of-type { /* The last element of its type */ }
p:nth-of-type(2) { /* The second element of its type */ }
p:nth-last-of-type(2) { /* The second-to-last element of its type */ }
p:only-of-type { /* Elements that are the only ones of their type */ }

/* Other pseudo-classes */
:root { /* The root element (usually html) */ }
:empty { /* Elements that have no children */ }
:not(.active) { /* Elements that don't match the selector */ }
:is(h1, h2, h3) { /* Elements that match any of the selectors */ }
:where(h1, h2, h3) { /* Similar to :is(), but with 0 specificity */ }
:has(> img) { /* Elements that contain at least one element matching the selector */ }

Pseudo-Elements

Pseudo-elements create "virtual" elements that don't exist in the HTML but can be styled with CSS.

/* First line of text */
p::first-line {
    font-weight: bold;
}

/* First letter of text */
p::first-letter {
    font-size: 2em;
    float: left;
    margin-right: 0.1em;
}

/* Content before an element */
.card::before {
    content: "★";
    color: gold;
    margin-right: 0.5em;
}

/* Content after an element */
.external-link::after {
    content: " ↗";
    font-size: 0.8em;
}

/* Selection styling */
::selection {
    background-color: #0066cc;
    color: white;
}

/* Placeholder text */
input::placeholder {
    color: #999;
    font-style: italic;
}

/* List markers */
li::marker {
    color: #0066cc;
    font-weight: bold;
}

Combinators

Combinators allow you to select elements based on their relationship to other elements.

/* Descendant combinator (space) */
.container p {
    /* Selects all p elements inside .container */
}

/* Child combinator (>) */
.container > p {
    /* Selects all p elements that are direct children of .container */
}

/* Adjacent sibling combinator (+) */
h2 + p {
    /* Selects p elements that immediately follow h2 elements */
}

/* General sibling combinator (~) */
h2 ~ p {
    /* Selects all p elements that follow h2 elements */
}

/* Combining multiple selectors */
.container > h2 + p {
    /* Selects p elements that immediately follow h2 elements that are direct children of .container */
}

Complex Selector Examples

Here are some examples of complex selectors that combine multiple techniques:

/* Select all external links */
a[href^="http"]:not([href*="example.com"]) {
    color: #0066cc;
}

/* Style the first paragraph after each heading */
h2 + p::first-line {
    font-weight: bold;
}

/* Style list items based on their position */
ul > li:nth-child(odd) {
    background-color: #f0f0f0;
}

/* Style form elements based on their state */
input:not([type="submit"]):focus {
    border-color: #0066cc;
    outline: none;
    box-shadow: 0 0 0 2px rgba(0, 102, 204, 0.3);
}

/* Style elements with specific data attributes */
[data-status="success"] {
    color: green;
}

[data-status="error"] {
    color: red;
}

/* Style elements based on their content */
p:has(> strong) {
    background-color: #f0f0f0;
}

/* Style elements based on their position in the document */
:is(h2, h3, h4):not(:first-child) {
    margin-top: 2em;
}

Specificity

Specificity determines which CSS rule is applied when multiple rules target the same element. Understanding specificity is crucial for writing maintainable CSS.

/* Specificity hierarchy (from lowest to highest) */

/* Type selectors (e.g., h1) and pseudo-elements (e.g., ::before) */
/* Specificity: 0-0-1 */
p { color: black; }
p::first-line { color: blue; }

/* Class selectors (e.g., .example), attribute selectors (e.g., [type="text"]), and pseudo-classes (e.g., :hover) */
/* Specificity: 0-1-0 */
.text { color: red; }
[type="text"] { color: green; }
p:hover { color: orange; }

/* ID selectors (e.g., #example) */
/* Specificity: 1-0-0 */
#title { color: purple; }

/* Inline styles */
/* Specificity: 1-0-0-0 */

Inline styled text

/* !important (avoid using this when possible) */ /* Overrides all other styles */ p { color: yellow !important; }

Calculating Specificity

Specificity is calculated as a four-part value: a-b-c-d

/* Examples of specificity calculations */

/* Specificity: 0-0-0-1 */
p { color: black; }

/* Specificity: 0-0-1-0 */
.text { color: red; }

/* Specificity: 0-1-0-0 */
#title { color: purple; }

/* Specificity: 0-0-1-1 */
p.text { color: green; }

/* Specificity: 0-1-0-1 */
p#title { color: blue; }

/* Specificity: 0-1-1-0 */
#title.text { color: orange; }

/* Specificity: 0-1-1-1 */
p#title.text { color: yellow; }

/* Specificity: 0-0-2-1 */
p.text.active { color: pink; }

/* Specificity: 0-0-1-2 */
div p.text { color: brown; }

/* Specificity: 0-0-2-2 */
div.container p.text { color: cyan; }

Continue to Part 2

Continue to Part 2 to learn about Advanced Layouts, Advanced Animations, CSS Optimization, and Future CSS.