marcj / css-element-queries

CSS Element-Queries aka Container Queries. High-speed element dimension/media queries in valid css.
http://marcj.github.io/css-element-queries/
MIT License
4.27k stars 487 forks source link

Does element-queries also work inside the shadow DOM? #255

Closed tkless closed 5 years ago

tkless commented 5 years ago

This does not work:

<!DOCTYPE html>
<meta charset="utf-8">

<script src="../libs/elementQueries/ResizeSensor.js"></script>
<script src="../libs/elementQueries/ElementQueries.js"></script>

<body>
<script>
  let shadow = document.body.attachShadow({mode: 'open'});
  const div = document.createElement( 'div' );
  shadow.appendChild( div );
  div.innerHTML = `
    <style>
      .example-1 {
        max-width: 500px;
        border: 1px solid silver;
        background-color: #eee;
        margin: auto;
        padding: 5px;
        text-align: center;
        min-width: 120px;
        transition:all .2s ease;
      }

      .example-1[min-width~="400px"] {
        padding: 80px;
      }

      .example-1[min-width~="200px"] {
        text-align: left;
        font-size: 12px;
      }
    </style>

    <div class="example-1">
      <h2>Demo 1</h2>
      This is content from the first responsive demo without media queries. It uses the element
      queries
      provided by this library.
    </div>
  `;

</script>
marcj commented 5 years ago

Did you test it? If yes, then you have your answer. If not, then I guess it doesn't work.

tkless commented 5 years ago

The website says: "It's exactly what we need when it comes to responsive Web Components." Web Components are mostly working with Shadow DOM. So it will be really great if Element Queries working with Shadow DOM.

marcj commented 5 years ago

Shadow DOM isn't used mostly, quite the opposite, since it doesn't have good cross-browser support.

So it will be really great if Element Queries working with Shadow DOM.

I agree, I hope we get it working 👍

lkraav commented 5 years ago

Web components are accelerating strong, I did the research, and am building my next platform update on it.

See lit-element, ionic v4, Vaadin, etc

Shadow DOM is ready to be used today.

marcj commented 5 years ago

I'm afraid that's not quite true, but I hope so in the future.

https://caniuse.com/#feat=shadowdomv1

screenshot 2019-01-21 at 18 50 21

Ionic is using Angular, which is using per default emulated Shadow DOM, where css-element-queries works. Vaadin emulates it as well, as you can see since they support IE 11+, which officially doesn't support Shadow Dom. Never heard of it and lit-element tho'.

However, if you want to contribute, to support native shadow DOM, feel free to create a PR. 👍

pmbednarczyk commented 4 years ago

Yeah for me element queries wouldbe the most valuable in shadow-doom (web-components). It's bad it's not supported ;(

image

tkless commented 4 years ago

In our project/framework we use Shadow Dom. We find a solution, that works great for us, as element queries with only few lines of code:

/**
 * @summary sets observed responsive breakpoints for an element
 * @param {Element} element
 * @param {Object} [breakpoints = { SM: 384, MD: 576, LG: 768, XL: 960 }]
 */
function responsive( element, breakpoints = { SM: 384, MD: 576, LG: 768, XL: 960 } ) {
​
  if ( window.ResizeObserver )
    new ResizeObserver( updateBreakpoints ).observe( element );
  else {
    // fallback with MutationObserver if Resize Observer is not supported by the browser
    const observer = new MutationObserver( mutations => mutations.forEach( mutation => mutation.type === 'attributes' && mutation.attributeName === 'style' && updateBreakpoints() ) );
    observer.observe( element, { attributes: true } );
    document.body.querySelectorAll( '*' ).forEach( element => observer.observe( element, { attributes: true } ) );
    window.addEventListener( 'resize', updateBreakpoints, false );
    updateBreakpoints();
  }
​
  function updateBreakpoints() {
    for ( const key in breakpoints )
      element.classList[ element.offsetWidth >= breakpoints[ key ] ? 'add' : 'remove' ]( key );
  }
​
}

->Hier the link to this code snippet in our project

-> For demo go here

Try it out :)

pmbednarczyk commented 4 years ago

Really nice, thank you :). It looks promising and may resolve my issue :). I will just have to properly implement it into my SCSS mixins, probably something like:

@mixin min-hd {
    #main-wrapper.XL & { @content; }
}