Color Mode

Media Queries and Print Styles

Media queries allow you to apply different styles based on device characteristics like screen width, orientation, or media type. They are essential for creating responsive designs that work well across different devices and contexts. In this course, we will use media queries extensively to build adaptive layouts.

Understanding @media Queries

The @media rule applies styles conditionally based on the result of one or more media queries. Each media query tests for specific conditions, and the enclosed styles only apply when those conditions are met.

Basic Syntax

The basic structure of a media query includes the @media keyword, an optional media type, and one or more conditions:


      /* Traditional syntax */
      @media screen and (min-width: 768px) {
          .container {
              max-width: 1200px;
              margin: 0 auto;
          }
      }
  

In this example, the styles inside the media query only apply when the viewport is at least 768 pixels wide and the media type is screen.

Modern Range Syntax

Modern CSS supports a more intuitive range syntax for width and height queries. This syntax uses comparison operators that read more naturally:


      /* Modern range syntax */
      @media (width >= 768px) {
          .container {
              max-width: 1200px;
              margin: 0 auto;
          }
      }

      /* Range between two values */
      @media (768px <= width < 1024px) {
          .sidebar {
              width: 250px;
          }
      }
  

The range syntax is supported in all modern browsers. It makes media queries easier to read and write, especially when checking ranges between two values.

Common Media Features

Beyond width, media queries can test many different features:


      /* Orientation */
      @media (orientation: landscape) {
          .gallery {
              grid-template-columns: repeat(4, 1fr);
          }
      }

      /* Dark mode */
      @media (prefers-color-scheme: dark) {
          body {
              background: #1a1a1a;
              color: #f0f0f0;
          }
      }

      /* Reduced motion for accessibility */
      @media (prefers-reduced-motion: reduce) {
          * {
              animation-duration: 0.01ms !important;
              transition-duration: 0.01ms !important;
          }
      }
  

Nested Media Queries

With modern CSS nesting, you can write media queries directly inside your selectors, keeping related styles together and improving organization:


      /* Traditional unnested approach */
      .card {
          padding: 10px;
          font-size: 0.9rem;
      }

      @media (width >= 768px) {
          .card {
              padding: 20px;
              font-size: 1rem;
          }
      }

      @media (width >= 1024px) {
          .card {
              padding: 30px;
              font-size: 1.1rem;
          }
      }
  

      /* Modern nested approach */
      .card {
          padding: 10px;
          font-size: 0.9rem;

          @media (width >= 768px) {
              padding: 20px;
              font-size: 1rem;
          }

          @media (width >= 1024px) {
              padding: 30px;
              font-size: 1.1rem;
          }
      }
  

The nested approach keeps all styles for .card in one place, making it easier to understand how the component adapts to different screen sizes.

Throughout this course, you are encouraged to use nested media queries to keep your responsive styles organized. Both approaches work, but nesting improves maintainability.

Common Breakpoint Strategies

Breakpoints are the specific widths where your layout changes to accommodate different screen sizes. Rather than targeting specific devices, choose breakpoints based on where your content naturally needs to adapt.


      /* Common breakpoint pattern */
      .navigation {
          display: flex;
          flex-direction: column;

          @media (width >= 768px) {
              flex-direction: row;
              gap: 2rem;
          }

          @media (width >= 1200px) {
              gap: 3rem;
              padding: 0 2rem;
          }
      }
  

Common breakpoint ranges include small devices (up to 768px), tablets (768px to 1024px), and desktops (1024px and up). However, these are guidelines rather than strict rules. The best breakpoints are determined by your specific content and design.

Print Styles with @print

The @print media type allows you to create styles specifically for printed pages. Print stylesheets help ensure your content looks professional and readable when printed, removing unnecessary elements and optimizing the layout for paper.

Basic Print Media Query

Use @media print to target print output:


      /* Styles for print only */
      @media print {
          body {
              font-size: 12pt;
              color: black;
              background: white;
          }

          a {
              color: black;
              text-decoration: underline;
          }
      }
  

Hiding Elements for Print

Navigation menus, sidebars, and interactive elements are typically unnecessary in print. Hide them to focus on the main content:


      /* Unnested approach */
      @media print {
          nav,
          .sidebar,
          .no-print,
          button,
          video {
              display: none;
          }
      }
  

      /* Nested approach with modern CSS */
      nav {
          display: flex;
          gap: 1rem;

          @media print {
              display: none;
          }
      }

      .sidebar {
          width: 250px;
          background: #f5f5f5;

          @media print {
              display: none;
          }
      }
  

Page Breaks

Control where page breaks occur to prevent awkward splits in your content:


      @media print {
          h1, h2, h3 {
              page-break-after: avoid;
          }

          section {
              page-break-inside: avoid;
          }

          .chapter {
              page-break-before: always;
          }
      }
  

Displaying Link URLs

Since printed pages cannot have clickable links, you can display the URL next to each link using CSS generated content:


      @media print {
          a::after {
              content: " (" attr(href) ")";
              font-size: 0.9em;
              color: #555;
          }

          /* Don't show URLs for anchor links */
          a[href^="#"]::after {
              content: "";
          }
      }
  

Be mindful that very long URLs can break your print layout. Consider limiting which links display URLs or truncating extremely long ones.

Common Print Styling Patterns

Here is a comprehensive print stylesheet example combining multiple best practices:


      @media print {
          /* Reset for print */
          * {
              background: transparent !important;
              color: black !important;
              box-shadow: none !important;
              text-shadow: none !important;
          }

          /* Page settings */
          @page {
              margin: 2cm;
          }

          body {
              font-size: 12pt;
              line-height: 1.5;
          }

          /* Typography */
          h1, h2, h3 {
              page-break-after: avoid;
              page-break-inside: avoid;
          }

          /* Images */
          img {
              max-width: 100% !important;
              page-break-inside: avoid;
          }

          /* Tables */
          table {
              border-collapse: collapse;
          }

          th, td {
              border: 1px solid black;
              padding: 0.5em;
          }

          /* Hide non-essential elements */
          nav,
          aside,
          .no-print,
          .advertisement,
          button,
          video,
          audio {
              display: none !important;
          }

          /* Show link URLs */
          a[href]::after {
              content: " (" attr(href) ")";
          }

          a[href^="#"]::after,
          a[href^="javascript:"]::after {
              content: "";
          }
      }
  

Practical Example: Responsive Card with Print Support

Here is a complete example showing how media queries and print styles work together in a real component:


      .card {
          padding: 1rem;
          background: white;
          border: 1px solid #ddd;
          border-radius: 8px;

          /* Tablet and larger */
          @media (width >= 768px) {
              padding: 1.5rem;
              display: grid;
              grid-template-columns: 200px 1fr;
              gap: 2rem;
          }

          /* Desktop */
          @media (width >= 1200px) {
              padding: 2rem;
              grid-template-columns: 300px 1fr;
          }

          /* Print styles */
          @media print {
              border: 2px solid black;
              border-radius: 0;
              page-break-inside: avoid;
              margin-bottom: 1cm;
          }

          .card-image {
              width: 100%;
              height: auto;

              @media print {
                  max-width: 200px;
              }
          }

          .card-actions {
              display: flex;
              gap: 1rem;
              margin-top: 1rem;

              @media print {
                  display: none;
              }
          }
      }
  

This example demonstrates responsive design with nested media queries and appropriate print handling, all organized within the component's styles.

Looking Ahead

Media queries are a fundamental tool for responsive design, and you will use them extensively throughout this course. In the next learning activity, we will explore mobile-first design strategies, which build on these concepts to create more efficient and maintainable responsive layouts.