Skip to main content

CSS Media Queries Tutorial with Hands-On Examples

Introduction to Media Queries

Media queries are a powerful feature in CSS that allow you to apply different styles based on the characteristics of the device or browser viewing your web page. They are a fundamental part of responsive web design, enabling you to create layouts that adapt to different screen sizes and device capabilities.

Media Query Syntax

The basic syntax of a media query is as follows:

@media [media-type] and (media-feature) {
    /* CSS rules */
}

Here's a simple example:

Try it:

Media Types

Media types describe the general category of a device. The most common types are:

  • all: Suitable for all devices
  • screen: For computer screens, tablets, and smartphones
  • print: For printers and print preview mode

Try it:

This text is visible on screen.

Media Features

Media features describe specific characteristics of the user agent, output device, or environment. Some common features include:

  • width and height: The width or height of the viewport
  • aspect-ratio: The ratio between width and height of the viewport
  • orientation: The orientation of the device (landscape or portrait)
  • resolution: The resolution of the output device

Try it:

Logical Operators

You can use logical operators to create more complex media queries:

  • and: Combines multiple media features
  • not: Negates a media query
  • only: Applies styles only if the entire query matches
  • , (comma): Combines multiple media queries into one rule

Try it:

Common Breakpoints

While breakpoints can be customized for each project, here are some common breakpoints:

  • Mobile: 320px - 480px
  • Tablet: 481px - 768px
  • Laptop: 769px - 1024px
  • Desktop: 1025px and above

Try it:

This text changes based on screen size.

Responsive Design with Media Queries

Media queries are essential for creating responsive designs. Here's an example of a simple responsive layout:

Try it:

Column 1
Column 2
Column 3

Comprehensive Best Practices for Responsive Web Design

  • Use relative units (em, rem, %) instead of fixed units (px) for better scalability:
    /* Bad */
    .container { width: 960px; }
    
    /* Good */
    .container { width: 90%; max-width: 1200px; }
  • Adopt a mobile-first approach, using min-width queries to scale up:
    /* Mobile styles (default) */
    .nav-menu { display: none; }
    
    /* Tablet and up */
    @media (min-width: 768px) {
        .nav-menu { display: flex; }
    }
  • Group media queries at the end of your CSS file:
    /* Styles for all screen sizes */
    ...
    
    /* Media Queries */
    @media (min-width: 768px) { ... }
    @media (min-width: 1024px) { ... }
  • Optimize images and use responsive image techniques:
    <img src="small.jpg"
         srcset="small.jpg 300w, medium.jpg 600w, large.jpg 1200w"
         sizes="(max-width: 600px) 300px, (max-width: 1200px) 600px, 1200px"
         alt="Responsive image example">
  • Implement flexible layouts using CSS Flexbox or Grid:
    .container {
        display: flex;
        flex-wrap: wrap;
    }
    .item {
        flex: 1 1 300px;
        margin: 10px;
    }
  • Use fluid typography:
    html {
        font-size: calc(16px + 0.5vw);
    }
  • Consider touch targets for mobile devices:
    .button {
        min-width: 44px;
        min-height: 44px;
        padding: 10px;
    }
  • Implement responsive navigation patterns:
    @media (max-width: 767px) {
        .nav-menu {
            display: none;
        }
        .hamburger-menu {
            display: block;
        }
    }
  • Use feature queries for progressive enhancement:
    @supports (display: grid) {
        .container {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        }
    }
  • Optimize performance with lazy loading:
    <img src="placeholder.jpg" data-src="actual-image.jpg" class="lazy" alt="Lazy loaded image">
    
    <script>
    document.addEventListener("DOMContentLoaded", function() {
        var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
        if ("IntersectionObserver" in window) {
            let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
                entries.forEach(function(entry) {
                    if (entry.isIntersecting) {
                        let lazyImage = entry.target;
                        lazyImage.src = lazyImage.dataset.src;
                        lazyImage.classList.remove("lazy");
                        lazyImageObserver.unobserve(lazyImage);
                    }
                });
            });
            lazyImages.forEach(function(lazyImage) {
                lazyImageObserver.observe(lazyImage);
            });
        }
    });
    </script>
  • Use CSS custom properties for responsive values:
    :root {
        --main-color: #007bff;
        --padding: 20px;
    }
    
    @media (min-width: 768px) {
        :root {
            --padding: 40px;
        }
    }
    
    .container {
        color: var(--main-color);
        padding: var(--padding);
    }

Remember to thoroughly test your design on various devices and screen sizes, and regularly review and refactor your CSS to maintain clean, efficient code as your project evolves.

Advanced Techniques

Here are some advanced techniques using media queries:

1. Container Queries (Experimental)

Container queries allow you to style elements based on the size of their container, not just the viewport.

@container (min-width: 400px) {
    .card {
        display: flex;
    }
}

2. Feature Queries

Use @supports to check for browser support of certain CSS properties:

@supports (display: grid) {
    .container {
        display: grid;
    }
}

3. Combining Media Queries with JavaScript

You can use JavaScript to detect media query changes:

const mediaQuery = window.matchMedia('(min-width: 768px)');

function handleTabletChange(e) {
    if (e.matches) {
        console.log('Tablet mode');
    }
}

mediaQuery.addListener(handleTabletChange);
handleTabletChange(mediaQuery);

Comments & Discussion

Facing issues? Have questions? Post them here! We're happy to help!