mrtnvh.com

Container
Queries

The next step towards a truly modular CSS

Widgets

  • Gauge
  • Pie chart
  • Weather
  • Users

All widgets are customizable by user

Illustration of a dashboard

Widgets

  • Gauge
  • Pie chart
  • Weather
  • Users

All widgets are customizable by user

Illustration of a dashboard

Widgets

  • Gauge
  • Pie chart
  • Weather
  • Users

All widgets are customizable by user

Illustration of a dashboard

                  

                  .dashboard { /* ... */ }
        
                  .widget { /* ... */ }
        
                  .widget--gauge { /* ... */ }
                  .widget--pie { /* ... */ }
                  .widget--weather { /* ... */ }
                  .widget--users { /* ... */ }
                
Illustration of a dashboard

                  

                  .dashboard { /* ... */ }
        
                  .widget { /* ... */ }
                  .widget--large { /* ... */ }
        
                  .widget--gauge { /* ... */ }
                  .widget--weather { /* ... */ }
                  .widget--users { /* ... */ }
                  
                  .widget--pie { /* ... */ }
                  .widget--pie.widget--large { /* ... */ }
                
Illustration of a dashboard

                  

                  .dashboard { /* ... */ }
        
                  .widget { /* ... */ }
                  .widget--large { /* ... */ }
        
                  .widget--gauge { /* ... */ }
                  .widget--users { /* ... */ }
                  
                  .widget--pie { /* ... */ }
                  .widget--pie.widget--large { /* ... */ }
        
                  .widget--weather { /* ... */ }
                  .widget--weather.widget--large { /* ... */ }
                
Illustration of a dashboard

Reusability

  • Widgets will be part of a design system.
  • No knowledge,nor control of layout implementations
How to guarantee on optimal layout?

Reusability


                  
                  

Each dependant application is required to explicitly set widget variant.


                  // 1. Application business logic to for dashboard grid layout
                  function getDashboardGrid() {}
                  
                  // 2. Application business logic for widget layout
                  function getWeatherWidgetSize() {}
                
Illustration of a dashboard

Automatic reusability

How can each dependant create most optimal widget layout?

Media Queries?

  • 🚫 Acts on viewport dimensions
  • 🚫 No exact correlation between viewport and final implementation

ResizeObserver?

  • 🚫 Wait for client side JS
  • 🚫 SSR
  • => Flash Of Unstyled Content
  • => Layout Shifts

Automatic reusability

How can each dependant create most optimal widget layout?

What are we looking for?

  • CSS
  • Set user preference in dependant layout
  • Acts on container dimensions

Good news!

Something's cooking.

Maarten Van Hoof

iO digital
  • Senior Front-end Developer
  • Developer Advocate

Warning

The following demo features experiments performed on a draft specification, under the supervision of me. Accordingly, I and mostly just me, must insist that no one attempts to deploy any of the following examples to production.

Timeline of responsive webdesign
Timeline of responsive webdesign

Container Queries

Allows any element with both size & layout containment to be queried using a new @container rule, with similar syntax to existing media-queries.


              .container {
                contain: layout inline-size style;
              }
        
              @container (min-width: 500px) {
                .container__content {
                  /* ... */
                }
              }
            

                  

                  .dashboard { /* ... */ }
        
                  .widget { /* ... */ }
                  .widget--large { /* ... */ }
        
                  .widget--gauge { /* ... */ }
                  .widget--users { /* ... */ }
                  
                  .widget--pie { /* ... */ }
                  .widget--pie.widget--large { /* ... */ }
        
                  .widget--weather { /* ... */ }
                  .widget--weather.widget--large { /* ... */ }
                
Illustration of a dashboard

                  

                  /* dashboard.css */
                  .dashboard { /* ... */ }
              

                  /* widget.css */
                  .widget { /* ... */ }
                  .widget--large { /* ... */ }
        
                  .widget--gauge { /* ... */ }
                  .widget--users { /* ... */ }
                  .widget--pie { /* ... */ }
        
                  .widget--weather { /* ... */ }
                  .widget--weather.widget--large { /* ... */ }
              
Illustration of a dashboard

                  

                  .widget { /* ... */ }
                  .widget--large { /* ... */ }
        
                  .widget--weather { /* ... */ }
                  .widget--weather.widget--large { /* ... */ }
              
Illustration of a dashboard

                  

                  .widget {
                    contain: layout inline-size style;
                  }
                  .widget--large { /* ... */ }
        
                  .widget--weather { /* ... */ }
                  .widget--weather.widget--large { /* ... */ }
              
Illustration of a dashboard

                  

                  .widget {
                    contain: layout inline-size style;
                  }
        
                  .widget--weather { /* ... */ }
        
                  @container (min-width: 450px) {
                    .widget { /* ... */ }
                    .widget--weather { /* ... */ }
                  }
              

🚫 Elements queried must be inside a containment context.

Illustration of a dashboard

                  

                  .widget {
                    contain: layout inline-size style;
                  }
        
                  .widget--weather .widget__body { /* ... */ }
        
                  @container (min-width: 450px) {
                    .widget__body { /* ... */ }
                    .widget--weather .widget__body { /* ... */ }
                  }
              

✅ Elements queried must be inside a containment context.

Illustration of a dashboard

Automatic reusability

How can each dependant create most optimal widget layout?

  • ✅ CSS
  • ✅ Set user preference in dependant layout
         CSS Grid or Flexbox
  • ✅ Dependencies act on own container dimensions
         Container Queries

Spec. Status

Leading force: Miriam Suzanne

  • Invited Expert at the W3C CSS Working Group
  • Core contributor to the Sass
  • Smashing Magazine, CSS-Tricks, ...

Status: Draft

Extension and part of CSS Containment spec.

Testable: Chrome Canary - chrome://flags/#enable-container-queries flag.

Experiments

Miriam Suzanne's Collection of CodePens

WIP

All progress available on CSSWG Drafts GitHub Repo

TIL

Container Queries: Allows any element with both size & layout containment to be queried using a new @container rule, with similar syntax to existing media-queries.


                .container {
                  contain: layout inline-size style;
                }
                

                @container (min-width: 100px) {
                  .child-of-container { /* ... */ }
                }
                

FIN

Find me

mrtnvh.com@mrtnvh

iodigital.com
Peace

Credits

Specification

Examples

Links