question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Use of :root inside media queries

See original GitHub issue

Does this ponyfill support the changing of a property declared on :root if it is changed with a media query?

E.g.

:root {
  --h1-color: green;
}
@media (max-width: 1024px) {
  :root {
    --h1-color: red;
  }
}

h1 {
  color: var(--h1-color);
}

I’d expect to see both values transformed so that the media query is applied to the h1 but with the new fixed value such as:

h1 {
  color: green;
}

@media (max-width: 1024px) {
  h1{
    color: red;
  }
}

Is this currently possible? I’d assume not, since ensuring the media queries are only applied to the correct elements is the tough part.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:7
  • Comments:14 (8 by maintainers)

github_iconTop GitHub Comments

10reactions
jhildenbiddlecommented, Sep 3, 2019

This feature is now planned for the upcoming 2.0 release sometime possibly in the future 🤷‍♂

The next major update of the ponyfill will include quite a few optimizations that dramatically increase the performance of the ponyfill. Much of this work is currently in progress for #55 . As a result of this work, processing custom properties defined in media queries should be doable without significantly impacting performance.

To be clear, the ponyfill will remain limited to processing :root-level custom property declarations only, although with this feature added it will also handle :root-level declarations with @media rules (which are currently ignored in 1.0).

For example:

:root {
  --color: red;
}

p {
  color: var(--color);
}

@media (min-width: 500px) {
  :root {
    --color: blue;
  }
}

1.x output:

p {
  color: red;
}

2.x output:

p {
  color: red;
}

@media (min-width: 500px) {
  p {
    color: blue;
  }
}

No ETA unfortunately, but I will begin work on this once #55 is complete.

4reactions
jhildenbiddlecommented, Feb 28, 2019

@IAmAdamTaylor, @rtynio, @mhemesath

I wanted to offer a a solution for those needing media query and CSS custom property support while we discuss adding this functionality to the ponyfill. I’ve created a demo for review:

Here’s how it works:

  1. Create an object that contains your app’s custom properties grouped by media queries:

    const mqVars = {
      "all": {
        "--my-color": "red"
      },
      "(min-width: 600px)": {
        "--my-color": "blue"
      },
      "(min-width: 800px)": {
        "--my-color": "green"
      }
    }
    
  2. Create a function that returns the “current” custom properties based on the active media queries:

    function getActiveVars() {
      const activeVars = {};
    
      // Get custom property values for all active media queries
      for (const key in mqVars) {
        if (window.matchMedia(key).matches) {
          Object.assign(activeVars, mqVars[key]);
        }
      }
    
      return activeVars;
    }
    
  3. Call the ponyfill, passing the “current” custom properties from the above function:

    cssVars({
      variables: getActiveVars()
    });
    
  4. Create a resize event listener that contains a debounced ponyfill call with custom properties from all active media queries passed via options.variables:

    let resizeTimer;
    
    window.addEventListener('resize', function (evt) {
      clearTimeout(resizeTimer);
      resizeTimer = setTimeout(function () {
        cssVars({
          variables: getActiveVars()
        });
      }, 250);
    });
    

This approach won’t handle media queries like @media print because not all media queries are tied to a resize event, the lack of native window.matchMedia() support means not IE9 support 🤷‍♂️, and you’ll notice a restyling delay while waiting for the 250ms delay before the last resize event calls the ponyfill and new CSS is generated. But… it works.

The interesting thing about this approach is that it could be baked into the ponyfill fairly easily. A mediaQueries: true|false option would determine if the ponyfill behaves as it does today or performs steps similar to the ones described above. This would be much faster per-call than generating legacy-compatible CSS for all media queries (as described in my previous post), but it means the ponyfill has to do some work each time the active media queries change.

Thoughts?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Want CSS variables in media query declarations? Try this!
Let's see why CSS variables / custom properties fail in media queries + some workarounds to try.
Read more >
CSS native variables not working in media queries
As Oriol has answered, CSS Variables Level 1's var() cannot currently be used in media queries. However ...
Read more >
Using CSS Media Queries and Variables for Responsiveness
"In this article, we'll learn how to make responsiveness for manageable using CSS Media queries and Variables."
Read more >
CSS Using Variables in Media Queries - W3Schools
Here, we first declare a new local variable named --fontsize for the .container class. We set its value to 25 pixels. Then we...
Read more >
Using media queries - CSS: Cascading Style Sheets | MDN
A media query is composed of an optional media type and any number of media feature expressions, which may optionally be combined in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found