CSS Intermediate

Advanced CSS Techniques

CodingerWeb
CodingerWeb
23 views 80 min read

CSS Custom Properties (Variables)

CSS custom properties allow you to store values that can be reused throughout your stylesheet, making maintenance easier and enabling dynamic theming.

Defining and Using Variables

:root {
    --primary-color: #007bff;
    --secondary-color: #6c757d;
    --font-size-base: 16px;
    --spacing-unit: 1rem;
    --border-radius: 8px;
}

.button {
    background-color: var(--primary-color);
    font-size: var(--font-size-base);
    padding: var(--spacing-unit);
    border-radius: var(--border-radius);
}

/* Fallback values */
.element {
    color: var(--text-color, #333);
}

Dynamic Theming

/* Light theme */
:root {
    --bg-color: #ffffff;
    --text-color: #333333;
    --card-bg: #f8f9fa;
}

/* Dark theme */
[data-theme="dark"] {
    --bg-color: #1a1a1a;
    --text-color: #ffffff;
    --card-bg: #2d2d2d;
}

body {
    background-color: var(--bg-color);
    color: var(--text-color);
    transition: background-color 0.3s ease, color 0.3s ease;
}

Advanced Selectors

Attribute Selectors

/* Exact match */
input[type="email"] { }

/* Contains */
a[href*="example.com"] { }

/* Starts with */
a[href^="https://"] { }

/* Ends with */
img[src$=".jpg"] { }

/* Case insensitive */
input[type="EMAIL" i] { }

Structural Pseudo-classes

/* nth-child patterns */
li:nth-child(odd) { }      /* 1st, 3rd, 5th... */
li:nth-child(even) { }     /* 2nd, 4th, 6th... */
li:nth-child(3n) { }       /* Every 3rd element */
li:nth-child(3n+1) { }     /* 1st, 4th, 7th... */

/* Other structural selectors */
p:first-of-type { }
p:last-of-type { }
p:only-child { }
p:empty { }

Modern CSS Features

CSS Logical Properties

/* Traditional */
margin-left: 1rem;
margin-right: 1rem;

/* Logical (respects writing direction) */
margin-inline-start: 1rem;
margin-inline-end: 1rem;
margin-inline: 1rem; /* Shorthand */

/* Block direction */
margin-block-start: 1rem; /* margin-top in horizontal writing */
margin-block-end: 1rem;   /* margin-bottom in horizontal writing */

CSS Functions

/* calc() */
width: calc(100% - 2rem);
font-size: calc(1rem + 2vw);

/* min(), max(), clamp() */
width: min(100%, 600px);
height: max(200px, 50vh);
font-size: clamp(1rem, 4vw, 2rem);

/* Custom properties with calc */
:root {
    --base-size: 1rem;
}
.large-text {
    font-size: calc(var(--base-size) * 1.5);
}

CSS Shapes

.circle {
    width: 200px;
    height: 200px;
    clip-path: circle(50%);
}

.triangle {
    width: 200px;
    height: 200px;
    clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

.custom-shape {
    clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);
}

Performance Optimization

CSS Containment

.card {
    contain: layout style paint;
}

.sidebar {
    contain: layout;
}

Will-change Property

.animated-element {
    will-change: transform, opacity;
}

/* Remove after animation */
.animated-element.animation-complete {
    will-change: auto;
}

Critical CSS Patterns

/* Above-the-fold styles */
.hero {
    background-color: #007bff;
    color: white;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Lazy-loaded styles */
.below-fold {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.6s ease, transform 0.6s ease;
}

.below-fold.loaded {
    opacity: 1;
    transform: translateY(0);
}

Complete Advanced Example

<style>
/* CSS Custom Properties */
:root {
    --primary-hue: 210;
    --primary-sat: 100%;
    --primary-light: 50%;
    --primary-color: hsl(var(--primary-hue), var(--primary-sat), var(--primary-light));
    --primary-light-color: hsl(var(--primary-hue), var(--primary-sat), 90%);
    --primary-dark-color: hsl(var(--primary-hue), var(--primary-sat), 30%);
    
    --spacing-xs: 0.25rem;
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 2rem;
    --spacing-xl: 4rem;
    
    --font-size-sm: clamp(0.875rem, 2vw, 1rem);
    --font-size-base: clamp(1rem, 2.5vw, 1.125rem);
    --font-size-lg: clamp(1.25rem, 3vw, 1.5rem);
    --font-size-xl: clamp(1.75rem, 4vw, 2.5rem);
    
    --border-radius: 0.5rem;
    --box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
    --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Dark theme */
[data-theme="dark"] {
    --bg-color: #1a202c;
    --text-color: #f7fafc;
    --card-bg: #2d3748;
    --border-color: #4a5568;
}

/* Light theme */
[data-theme="light"] {
    --bg-color: #ffffff;
    --text-color: #1a202c;
    --card-bg: #f7fafc;
    --border-color: #e2e8f0;
}

* {
    box-sizing: border-box;
}

body {
    font-family: system-ui, -apple-system, sans-serif;
    background-color: var(--bg-color);
    color: var(--text-color);
    margin: 0;
    padding: 0;
    transition: var(--transition);
}

.container {
    max-width: 1200px;
    margin-inline: auto;
    padding-inline: var(--spacing-md);
}

/* Advanced Grid with CSS Subgrid */
.advanced-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: var(--spacing-lg);
    margin-block: var(--spacing-xl);
}

.card {
    background-color: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    padding: var(--spacing-lg);
    box-shadow: var(--box-shadow);
    transition: var(--transition);
    contain: layout style paint;
}

.card:hover {
    transform: translateY(-4px);
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}

/* Advanced button with custom properties */
.btn {
    --btn-color: var(--primary-color);
    --btn-hover-color: var(--primary-dark-color);
    --btn-text-color: white;
    
    background-color: var(--btn-color);
    color: var(--btn-text-color);
    border: none;
    padding: var(--spacing-sm) var(--spacing-md);
    border-radius: var(--border-radius);
    font-size: var(--font-size-base);
    cursor: pointer;
    transition: var(--transition);
    position: relative;
    overflow: hidden;
}

.btn::before {
    content: "";
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
    transition: left 0.5s;
}

.btn:hover {
    background-color: var(--btn-hover-color);
    transform: translateY(-2px);
}

.btn:hover::before {
    left: 100%;
}

/* CSS Shapes and Clip Path */
.shape-demo {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--spacing-md);
    margin-block: var(--spacing-lg);
}

.shape {
    width: 150px;
    height: 150px;
    background: linear-gradient(45deg, var(--primary-color), var(--primary-light-color));
    margin-inline: auto;
}

.circle {
    clip-path: circle(50%);
}

.triangle {
    clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

.hexagon {
    clip-path: polygon(30% 0%, 70% 0%, 100% 50%, 70% 100%, 30% 100%, 0% 50%);
}

.star {
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

/* Advanced animations */
@keyframes morphing {
    0% {
        clip-path: polygon(30% 0%, 70% 0%, 100% 50%, 70% 100%, 30% 100%, 0% 50%);
    }
    50% {
        clip-path: circle(50%);
    }
    100% {
        clip-path: polygon(30% 0%, 70% 0%, 100% 50%, 70% 100%, 30% 100%, 0% 50%);
    }
}

.morphing-shape {
    animation: morphing 3s ease-in-out infinite;
}

/* Theme toggle */
.theme-toggle {
    position: fixed;
    top: var(--spacing-md);
    right: var(--spacing-md);
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 50%;
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: var(--transition);
    z-index: 1000;
}

.theme-toggle:hover {
    transform: scale(1.1);
}

/* Responsive typography */
.responsive-text {
    font-size: var(--font-size-xl);
    line-height: 1.2;
    font-weight: 700;
    background: linear-gradient(45deg, var(--primary-color), var(--primary-light-color));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

/* Advanced layout with CSS Grid areas */
.advanced-layout {
    display: grid;
    grid-template-areas:
        "header header header"
        "nav main aside"
        "footer footer footer";
    grid-template-rows: auto 1fr auto;
    grid-template-columns: 200px 1fr 200px;
    min-height: 100vh;
    gap: var(--spacing-md);
}

@media (max-width: 768px) {
    .advanced-layout {
        grid-template-areas:
            "header"
            "nav"
            "main"
            "aside"
            "footer";
        grid-template-columns: 1fr;
    }
}

/* Performance optimizations */
.optimized-element {
    contain: layout style paint;
    will-change: transform;
}

.optimized-element.animation-complete {
    will-change: auto;
}
</style>

<div class="theme-toggle" onclick="toggleTheme()">🌓</div>

<div class="container">
    <h1 class="responsive-text">Advanced CSS Techniques</h1>
    
    <div class="advanced-grid">
        <div class="card">
            <h3>CSS Custom Properties</h3>
            <p>Dynamic theming with CSS variables</p>
            <button class="btn">Learn More</button>
        </div>
        
        <div class="card">
            <h3>Advanced Selectors</h3>
            <p>Powerful targeting with modern selectors</p>
            <button class="btn">Explore</button>
        </div>
        
        <div class="card">
            <h3>CSS Functions</h3>
            <p>calc(), clamp(), min(), max() and more</p>
            <button class="btn">Discover</button>
        </div>
    </div>
    
    <h2>CSS Shapes Demo</h2>
    <div class="shape-demo">
        <div class="shape circle"></div>
        <div class="shape triangle"></div>
        <div class="shape hexagon"></div>
        <div class="shape star morphing-shape"></div>
    </div>
</div>

<script>
function toggleTheme() {
    const currentTheme = document.documentElement.getAttribute("data-theme");
    const newTheme = currentTheme === "dark" ? "light" : "dark";
    document.documentElement.setAttribute("data-theme", newTheme);
    localStorage.setItem("theme", newTheme);
}

// Load saved theme
const savedTheme = localStorage.getItem("theme") || "light";
document.documentElement.setAttribute("data-theme", savedTheme);
</script>