CSS Advanced Content
This content has been divided into two parts for better readability:
- Part 1: CSS Architecture, Preprocessors, Custom Properties, and Advanced Selectors
- Part 2 (Current): Advanced Layouts, Advanced Animations, CSS Optimization, Future CSS, and Practice Exercises
Advanced Layouts
Modern CSS provides powerful layout techniques that go beyond the basics of Flexbox and Grid.
Advanced Grid Techniques
Grid Template Areas
Grid template areas provide a visual way to define your grid layout.
.container {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
min-height: 100vh;
gap: 1rem;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* Responsive layout */
@media (max-width: 768px) {
.container {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"content"
"sidebar"
"aside"
"footer";
}
}
Grid Auto Flow
The grid-auto-flow
property controls how the auto-placement algorithm works.
/* Default (row) */
.grid-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: row;
}
/* Column */
.grid-column {
display: grid;
grid-template-rows: repeat(3, 100px);
grid-auto-flow: column;
}
/* Dense packing algorithm */
.grid-dense {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: row dense;
}
Masonry Layout with Grid
While true masonry layout is coming to CSS Grid, you can create a similar effect with current features.
/* Masonry-like layout with CSS Grid */
.masonry-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 16px;
}
.masonry-item {
break-inside: avoid;
margin-bottom: 16px;
}
/* Different heights for items */
.masonry-item:nth-child(2n) {
grid-row-end: span 2;
}
.masonry-item:nth-child(3n) {
grid-row-end: span 3;
}
.masonry-item:nth-child(5n) {
grid-row-end: span 1;
}
Subgrid
Subgrid allows grid items to inherit the grid definition of their parent grid container.
.main-grid {
display: grid;
grid-template-columns: repeat(9, 1fr);
grid-template-rows: auto auto 1fr;
gap: 1rem;
}
.card {
grid-column: 2 / 9;
grid-row: 2 / 4;
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
}
.card__header {
grid-column: 1 / -1;
grid-row: 1;
}
.card__sidebar {
grid-column: 1 / 3;
grid-row: 2;
}
.card__content {
grid-column: 3 / -1;
grid-row: 2;
}
Multi-Column Layout
The multi-column layout module allows you to create newspaper-style columns.
.multi-column {
column-count: 3;
column-gap: 2rem;
column-rule: 1px solid #ddd;
}
/* Responsive columns */
@media (max-width: 768px) {
.multi-column {
column-count: 2;
}
}
@media (max-width: 480px) {
.multi-column {
column-count: 1;
}
}
/* Spanning across columns */
.multi-column h2 {
column-span: all;
margin-bottom: 1rem;
}
/* Avoiding column breaks */
.multi-column figure {
break-inside: avoid;
}
Aspect Ratio
The aspect-ratio
property allows you to maintain a consistent width-to-height ratio for elements.
/* 16:9 aspect ratio */
.video-container {
aspect-ratio: 16 / 9;
width: 100%;
background-color: #000;
}
/* 1:1 aspect ratio (square) */
.profile-image {
aspect-ratio: 1 / 1;
width: 100%;
object-fit: cover;
}
/* 4:3 aspect ratio */
.card {
aspect-ratio: 4 / 3;
width: 100%;
max-width: 400px;
}
Container Queries
Container queries allow you to style elements based on the size of their container, rather than the viewport.
/* Define a container */
.card-container {
container-type: inline-size;
container-name: card;
}
/* Style based on container width */
@container card (min-width: 400px) {
.card {
display: flex;
align-items: center;
}
.card__image {
width: 30%;
}
.card__content {
width: 70%;
padding-left: 1rem;
}
}
@container card (max-width: 399px) {
.card {
flex-direction: column;
}
.card__image {
width: 100%;
margin-bottom: 1rem;
}
.card__content {
width: 100%;
}
}
Scroll Snap
Scroll snap provides a way to create smooth, controlled scrolling experiences.
/* Basic scroll snap */
.scroll-container {
scroll-snap-type: y mandatory;
overflow-y: scroll;
height: 100vh;
}
.scroll-section {
scroll-snap-align: start;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
/* Horizontal scroll snap */
.carousel {
scroll-snap-type: x mandatory;
overflow-x: scroll;
display: flex;
width: 100%;
}
.carousel-item {
scroll-snap-align: center;
flex: 0 0 100%;
height: 300px;
}
/* Proximity scroll snap */
.gallery {
scroll-snap-type: x proximity;
overflow-x: scroll;
display: flex;
gap: 1rem;
}
.gallery-item {
scroll-snap-align: center;
flex: 0 0 300px;
}
Logical Properties
Logical properties allow you to write CSS that adapts to different writing modes and text directions.
/* Physical properties (direction-specific) */
.box-physical {
margin-left: 1rem;
margin-right: 2rem;
padding-top: 1rem;
padding-bottom: 2rem;
border-left: 1px solid black;
width: 200px;
height: 100px;
}
/* Logical properties (direction-agnostic) */
.box-logical {
margin-inline-start: 1rem;
margin-inline-end: 2rem;
padding-block-start: 1rem;
padding-block-end: 2rem;
border-inline-start: 1px solid black;
inline-size: 200px;
block-size: 100px;
}
/* Logical properties with shorthand */
.box-logical-shorthand {
margin-inline: 1rem 2rem; /* start end */
padding-block: 1rem 2rem; /* start end */
border-inline-start: 1px solid black;
inline-size: 200px;
block-size: 100px;
}
/* Logical properties with writing mode */
.box-vertical {
writing-mode: vertical-rl;
margin-inline: 1rem 2rem;
padding-block: 1rem 2rem;
border-inline-start: 1px solid black;
inline-size: 200px;
block-size: 100px;
}
CSS Shapes
CSS Shapes allow you to create non-rectangular shapes for text to flow around.
/* Circle shape */
.circle-shape {
width: 200px;
height: 200px;
background-color: #0066cc;
border-radius: 50%;
float: left;
shape-outside: circle(50%);
margin-right: 1rem;
}
/* Ellipse shape */
.ellipse-shape {
width: 300px;
height: 200px;
background-color: #0066cc;
border-radius: 50%;
float: left;
shape-outside: ellipse(40% 50%);
margin-right: 1rem;
}
/* Polygon shape */
.polygon-shape {
width: 200px;
height: 200px;
background-color: #0066cc;
clip-path: polygon(0 0, 100% 0, 100% 75%, 75% 100%, 0 100%);
float: left;
shape-outside: polygon(0 0, 100% 0, 100% 75%, 75% 100%, 0 100%);
margin-right: 1rem;
}
/* Image shape */
.image-shape {
width: 200px;
height: auto;
float: left;
shape-outside: url('shape.png');
shape-image-threshold: 0.5;
shape-margin: 1rem;
margin-right: 1rem;
}
Advanced Animations
CSS animations and transitions can be used to create complex, engaging user experiences.
Advanced Keyframe Animations
Keyframe animations allow you to define multiple steps in an animation sequence.
/* Multi-step animation */
@keyframes rainbow {
0% { background-color: red; }
14% { background-color: orange; }
28% { background-color: yellow; }
42% { background-color: green; }
56% { background-color: blue; }
70% { background-color: indigo; }
84% { background-color: violet; }
100% { background-color: red; }
}
.rainbow-box {
width: 100px;
height: 100px;
animation: rainbow 10s linear infinite;
}
/* Multiple animations */
.complex-animation {
animation:
fadeIn 1s ease-out,
slideUp 1.2s ease-out,
pulse 2s ease-in-out 1s infinite;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from { transform: translateY(50px); }
to { transform: translateY(0); }
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
Animation Properties
CSS provides several properties to control animations.
/* Animation properties */
.animated-element {
animation-name: slideIn;
animation-duration: 1s;
animation-timing-function: ease-out;
animation-delay: 0.5s;
animation-iteration-count: 3;
animation-direction: alternate;
animation-fill-mode: forwards;
animation-play-state: running;
}
/* Shorthand */
.animated-element-shorthand {
animation: slideIn 1s ease-out 0.5s 3 alternate forwards;
}
/* Pausing animations */
.animated-element:hover {
animation-play-state: paused;
}
/* Animation fill modes */
.fill-forwards {
animation: fadeIn 1s forwards; /* Keeps the final state */
}
.fill-backwards {
animation: fadeIn 1s 1s backwards; /* Applies the first keyframe during the delay */
}
.fill-both {
animation: fadeIn 1s 1s both; /* Combines forwards and backwards */
}
Cubic Bezier Timing Functions
Cubic bezier functions allow you to create custom timing functions for animations and transitions.
/* Predefined timing functions */
.ease { transition-timing-function: ease; }
.ease-in { transition-timing-function: ease-in; }
.ease-out { transition-timing-function: ease-out; }
.ease-in-out { transition-timing-function: ease-in-out; }
.linear { transition-timing-function: linear; }
/* Custom cubic bezier timing functions */
.custom-ease { transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); }
.bounce { transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); }
.smooth-start { transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
.elastic { transition-timing-function: cubic-bezier(0.68, -0.6, 0.32, 1.6); }
/* Steps timing function */
.steps { transition-timing-function: steps(5, end); }
.step-start { transition-timing-function: step-start; }
.step-end { transition-timing-function: step-end; }
Advanced Transitions
Transitions can be used to create smooth state changes.
/* Multiple transitions with different durations and delays */
.card {
background-color: white;
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition:
background-color 0.3s ease,
transform 0.5s ease,
box-shadow 0.5s ease;
}
.card:hover {
background-color: #f0f0f0;
transform: translateY(-10px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
/* Transition all properties */
.transition-all {
transition: all 0.5s ease;
}
/* Transition only specific properties */
.transition-specific {
transition-property: transform, opacity;
transition-duration: 0.5s;
transition-timing-function: ease;
}
/* Different durations for different properties */
.transition-different-durations {
transition-property: transform, opacity, background-color;
transition-duration: 0.5s, 1s, 2s;
transition-timing-function: ease;
}
3D Transforms
3D transforms allow you to create three-dimensional effects.
/* 3D space setup */
.scene {
perspective: 1000px;
perspective-origin: center center;
}
/* Basic 3D transforms */
.box-3d {
transform-style: preserve-3d;
transform: rotateX(45deg) rotateY(45deg) rotateZ(45deg);
}
/* 3D card flip */
.card-container {
perspective: 1000px;
width: 300px;
height: 200px;
}
.card-3d {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 1s;
}
.card-container:hover .card-3d {
transform: rotateY(180deg);
}
.card-front, .card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.card-back {
transform: rotateY(180deg);
}
/* 3D cube */
.cube {
width: 200px;
height: 200px;
position: relative;
transform-style: preserve-3d;
transform: rotateX(-30deg) rotateY(45deg);
transition: transform 1s;
}
.cube:hover {
transform: rotateX(-30deg) rotateY(225deg);
}
.cube-face {
position: absolute;
width: 200px;
height: 200px;
backface-visibility: hidden;
}
.front { transform: translateZ(100px); }
.back { transform: rotateY(180deg) translateZ(100px); }
.right { transform: rotateY(90deg) translateZ(100px); }
.left { transform: rotateY(-90deg) translateZ(100px); }
.top { transform: rotateX(90deg) translateZ(100px); }
.bottom { transform: rotateX(-90deg) translateZ(100px); }
Animation Performance
Optimizing animation performance is crucial for smooth user experiences.
/* Use transform and opacity for animations */
.performant-animation {
/* Good for animations - uses GPU acceleration */
transform: translateX(0);
opacity: 1;
transition: transform 0.3s, opacity 0.3s;
}
.performant-animation:hover {
transform: translateX(20px);
opacity: 0.8;
}
/* Avoid animating these properties */
.non-performant-animation {
/* Bad for animations - causes layout recalculations */
width: 100px;
height: 100px;
margin-left: 0;
background-color: blue;
transition: width 0.3s, height 0.3s, margin-left 0.3s, background-color 0.3s;
}
.non-performant-animation:hover {
width: 120px;
height: 120px;
margin-left: 20px;
background-color: red;
}
/* Use will-change for complex animations */
.complex-animation {
will-change: transform, opacity;
}
/* But don't overuse will-change */
.too-many-will-change {
/* This is excessive and can hurt performance */
will-change: transform, opacity, width, height, background-color, margin, padding;
}
CSS Animation Libraries
There are several CSS animation libraries that provide pre-built animations.
/* Animate.css example */
.animate__animated {
animation-duration: 1s;
animation-fill-mode: both;
}
.animate__fadeIn {
animation-name: fadeIn;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* Usage */
/* Content */
/* Custom animation library */
.fade-in {
animation: fadeIn 1s both;
}
.slide-up {
animation: slideUp 1s both;
}
.slide-down {
animation: slideDown 1s both;
}
.slide-left {
animation: slideLeft 1s both;
}
.slide-right {
animation: slideRight 1s both;
}
.bounce {
animation: bounce 1s both;
}
.pulse {
animation: pulse 1s infinite;
}
.shake {
animation: shake 0.5s both;
}
Animation Events
CSS animations can trigger JavaScript events.
/* HTML */
/* Animated Element */
/* JavaScript */
const element = document.getElementById('animated-element');
// Animation start event
element.addEventListener('animationstart', (event) => {
console.log('Animation started:', event.animationName);
});
// Animation iteration event
element.addEventListener('animationiteration', (event) => {
console.log('Animation iteration:', event.animationName);
});
// Animation end event
element.addEventListener('animationend', (event) => {
console.log('Animation ended:', event.animationName);
// Do something after animation completes
element.classList.add('animation-completed');
});
// Transition events
element.addEventListener('transitionstart', (event) => {
console.log('Transition started:', event.propertyName);
});
element.addEventListener('transitionend', (event) => {
console.log('Transition ended:', event.propertyName);
});
CSS Optimization
Optimizing your CSS can improve performance, reduce file size, and make your code more maintainable.
CSS Minification
Minification removes unnecessary characters from your CSS to reduce file size.
/* Before minification */
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
background-color: #f0f0f0;
}
.container .title {
font-size: 24px;
margin-bottom: 16px;
color: #333333;
}
/* After minification */
.container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;background-color:#f0f0f0}.container .title{font-size:24px;margin-bottom:16px;color:#333}
Critical CSS
Critical CSS is the minimum CSS required to render the above-the-fold content of a page.
/* Critical CSS inline in the head */
<head>
<style>
/* Critical CSS for above-the-fold content */
body { margin: 0; font-family: sans-serif; }
header { background-color: #333; color: white; padding: 1rem; }
.hero { height: 80vh; background-color: #f0f0f0; display: flex; align-items: center; justify-content: center; }
.hero h1 { font-size: 3rem; margin-bottom: 1rem; }
.hero p { font-size: 1.5rem; max-width: 600px; text-align: center; }
</style>
/* Load the rest of the CSS asynchronously */
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
</head>
CSS Code Splitting
Code splitting involves breaking your CSS into smaller, more manageable files.
/* Main CSS file */
@import 'base/reset.css';
@import 'base/typography.css';
@import 'layout/grid.css';
@import 'layout/header.css';
@import 'layout/footer.css';
@import 'components/buttons.css';
@import 'components/cards.css';
@import 'components/forms.css';
@import 'pages/home.css';
@import 'pages/about.css';
@import 'utils/helpers.css';
/* Conditional loading for specific pages */
/* home.html */
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="styles/pages/home.css">
/* about.html */
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="styles/pages/about.css">
CSS Specificity Management
Managing specificity helps avoid specificity wars and makes your CSS more maintainable.
/* High specificity (avoid) */
#header .navigation ul li a.active {
color: red;
}
/* Lower specificity (better) */
.nav-link.active {
color: red;
}
/* Using classes instead of IDs */
.header {
/* Instead of #header */
}
/* Avoiding unnecessary nesting */
.card .title {
/* Instead of .card .content .title */
}
/* Using :where() to reduce specificity */
:where(.error, .warning, .info) {
padding: 1rem;
border-radius: 4px;
margin-bottom: 1rem;
}
.error {
background-color: #ffebee;
color: #c62828;
}
.warning {
background-color: #fff8e1;
color: #f57f17;
}
.info {
background-color: #e3f2fd;
color: #1565c0;
}
CSS Performance Tips
Following these tips can help improve the performance of your CSS.
/* Avoid universal selectors */
* { /* Avoid */ }
/* Avoid deep nesting */
.header .nav .list .item .link { /* Avoid */ }
/* Use efficient selectors */
.menu-item { /* Good */ }
#menu .item { /* Less efficient */ }
/* Avoid expensive properties */
.box {
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Expensive */
border-radius: 4px; /* Expensive */
}
/* Group related styles */
.button {
/* Group all button styles together */
}
/* Avoid @import in CSS (use bundlers instead) */
@import url('typography.css'); /* Avoid in production */
/* Use shorthand properties */
.element {
margin: 10px 20px; /* Instead of setting each side separately */
padding: 10px; /* Instead of setting each side separately */
border: 1px solid #000; /* Instead of setting each property separately */
background: #f0f0f0 url('bg.png') no-repeat center center; /* Instead of setting each property separately */
}
CSS Linting and Formatting
Using linters and formatters helps maintain consistent, high-quality CSS code.
/* stylelint configuration example */
{
"extends": "stylelint-config-standard",
"rules": {
"indentation": 4,
"color-hex-case": "lower",
"color-hex-length": "short",
"color-no-invalid-hex": true,
"font-family-no-duplicate-names": true,
"font-family-no-missing-generic-family-keyword": true,
"function-calc-no-unspaced-operator": true,
"unit-no-unknown": true,
"property-no-unknown": true,
"declaration-block-no-duplicate-properties": true,
"selector-pseudo-class-no-unknown": true,
"selector-pseudo-element-no-unknown": true,
"selector-type-no-unknown": true,
"media-feature-name-no-unknown": true,
"at-rule-no-unknown": true,
"comment-no-empty": true,
"no-duplicate-selectors": true,
"no-empty-source": true,
"no-extra-semicolons": true,
"no-invalid-double-slash-comments": true,
"no-unknown-animations": true
}
}
CSS Analysis Tools
CSS analysis tools can help identify issues and optimize your CSS.
- Lighthouse: Audits your website for performance, accessibility, and more
- PurgeCSS: Removes unused CSS
- CSS Stats: Analyzes your CSS and provides statistics
- UnCSS: Removes unused CSS from your stylesheets
- Parker: Analyzes your CSS and provides metrics
- Specificity Graph: Visualizes the specificity of your selectors
Future CSS
CSS is constantly evolving, with new features being added to the specification. Here are some exciting features that are coming to CSS.
CSS Nesting
Native CSS nesting allows you to nest selectors within other selectors, similar to preprocessors like Sass.
/* Native CSS nesting */
.card {
background-color: white;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
& .title {
font-size: 1.5rem;
margin-bottom: 0.5rem;
}
& .content {
padding: 1rem;
& p {
margin-bottom: 1rem;
}
}
&:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
@media (max-width: 768px) {
& {
border-radius: 0;
}
}
}
CSS Houdini
CSS Houdini is a set of APIs that gives developers direct access to the CSS Object Model (CSSOM), enabling more powerful and performant CSS.
/* CSS Paint API example */
/* Register a paint worklet */
CSS.paintWorklet.addModule('confetti-paint.js');
/* Use the custom paint in CSS */
.confetti-button {
background-image: paint(confetti);
--confetti-color: #0066cc;
--confetti-size: 10;
}
/* confetti-paint.js */
registerPaint('confetti', class {
static get inputProperties() {
return ['--confetti-color', '--confetti-size'];
}
paint(ctx, size, properties) {
const color = properties.get('--confetti-color').toString();
const confettiSize = parseInt(properties.get('--confetti-size').toString());
// Draw confetti
for (let i = 0; i < 100; i++) {
const x = Math.random() * size.width;
const y = Math.random() * size.height;
ctx.fillStyle = color;
ctx.fillRect(x, y, confettiSize, confettiSize);
}
}
});
CSS Masonry Layout
Native CSS masonry layout will allow you to create masonry-style layouts without JavaScript.
/* Native CSS masonry layout */
.masonry-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-template-rows: masonry;
gap: 16px;
}
CSS Scroll-Linked Animations
Scroll-linked animations allow you to create animations that are tied to the scroll position.
/* CSS @scroll-timeline */
@scroll-timeline scroll-timeline {
source: selector(#scroll-container);
orientation: vertical;
scroll-offsets: 0%, 100%;
}
.parallax-element {
animation: parallax linear;
animation-timeline: scroll-timeline;
}
@keyframes parallax {
from {
transform: translateY(0);
}
to {
transform: translateY(-100px);
}
}
CSS Color Functions
New color functions provide more powerful ways to work with colors.
/* color-mix() function */
.mixed-color {
background-color: color-mix(in srgb, #0066cc 50%, #ff6b6b 50%);
}
/* color-contrast() function */
.contrast-color {
color: color-contrast(#0066cc vs white, black);
}
/* relative color syntax */
.lighter-color {
background-color: #0066cc;
color: #0066cc.lighter;
}
.darker-color {
background-color: #0066cc;
color: #0066cc.darker;
}
/* color spaces */
.oklch-color {
color: oklch(0.6 0.2 240);
}
.lab-color {
color: lab(56% -40 20);
}
CSS Scope
CSS scoping allows you to limit the scope of styles to a specific part of the document.
/* CSS @scope */
@scope (#theme-dark) {
.button {
background-color: #333;
color: white;
}
}
@scope (#theme-light) {
.button {
background-color: white;
color: #333;
}
}
/* Nested scopes */
@scope (#product-page) {
.title {
font-size: 2rem;
}
@scope (.product-card) {
.title {
font-size: 1.5rem;
}
}
}
CSS Layers
CSS cascade layers allow you to group styles and control their precedence.
/* CSS @layer */
@layer reset, base, components, utilities;
@layer reset {
/* Reset styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
}
@layer base {
/* Base styles */
body {
font-family: sans-serif;
line-height: 1.5;
color: #333;
}
}
@layer components {
/* Component styles */
.button {
padding: 0.5rem 1rem;
border-radius: 4px;
background-color: #0066cc;
color: white;
}
}
@layer utilities {
/* Utility styles */
.mt-1 { margin-top: 0.25rem; }
.mt-2 { margin-top: 0.5rem; }
.mt-3 { margin-top: 1rem; }
}
CSS Custom Highlight API
The CSS Custom Highlight API allows you to create custom text highlights.
/* CSS Custom Highlight API */
/* JavaScript */
const text = document.querySelector('p').textContent;
const searchTerm = 'example';
const ranges = [];
let startPos = text.indexOf(searchTerm);
while (startPos !== -1) {
const range = new Range();
range.setStart(document.querySelector('p').firstChild, startPos);
range.setEnd(document.querySelector('p').firstChild, startPos + searchTerm.length);
ranges.push(range);
startPos = text.indexOf(searchTerm, startPos + 1);
}
const highlight = new Highlight(...ranges);
CSS.highlights.set('search-results', highlight);
/* CSS */
::highlight(search-results) {
background-color: yellow;
color: black;
}
Practice Exercises
Now that you've learned advanced CSS concepts, it's time to practice! Here are some exercises to help you reinforce what you've learned.
Exercise 1: CSS Architecture
Refactor a CSS codebase using a CSS architecture methodology:
- Choose a CSS architecture methodology (BEM, SMACSS, OOCSS, etc.)
- Organize the CSS files according to the chosen methodology
- Rename classes to follow the naming convention
- Create a style guide documenting your approach
Exercise 2: Advanced Layouts
Create a complex layout using advanced CSS techniques:
- Use CSS Grid for the overall layout
- Implement a masonry-style section
- Create a card component with CSS shapes
- Make the layout responsive using container queries
- Use logical properties for direction-agnostic styling
Exercise 3: Advanced Animations
Create a series of advanced animations:
- Create a multi-step keyframe animation
- Implement a 3D card flip effect
- Create a parallax scrolling effect
- Animate a loading spinner with CSS
- Optimize the animations for performance
Exercise 4: CSS Optimization
Optimize a CSS codebase for performance:
- Analyze the CSS using tools like Lighthouse and CSS Stats
- Identify and remove unused CSS
- Refactor selectors to reduce specificity
- Implement critical CSS
- Minify the CSS for production
Exercise 5: Theme System
Create a comprehensive theme system using CSS custom properties:
- Define a set of base custom properties for colors, typography, spacing, etc.
- Create multiple themes (light, dark, high contrast, etc.)
- Implement a theme switcher using JavaScript
- Support user preference with the
prefers-color-scheme
media query - Ensure the themes are accessible with sufficient color contrast