GithubHelp home page GithubHelp logo

Comments (3)

tomhodgins avatar tomhodgins commented on June 14, 2024

Hi @scottkellum, thanks for the suggestion. I don't think I've seen this idea or an implementation that works like this before so it seems like you've discovered something useful :D

I'm not sure of the use cases or demos, or if this is related to element queries or a slightly different kind of query, but I have some brainstorms about prototyping it so we could play around with it. Do you have any implementations of this already?

One thing I'm not 100% sure how I'll do is resolve which element is the containing block for a given element, I'm not sure if this exists somewhere JS can check already, or if we'd have to describe logic like this.

Would this explain what you're looking for, if it worked?

<!DOCTYPE html>
<body>
  <sometimes-container>
    <absolute-child></absolute-child>
  </sometimes-container>
</body>
* {
  box-sizing-border-box;
}
body {
  margin: 0;
}
sometimes-container {
  display: block;
  margin: 100px;
  padding: 100px;
  border: 5px dotted red;
}
absolute-child {
  position: absolute;
  display: block;
  width: 50px;
  height: 50px;
  top: 0;
  left: 0;
  border: 5px dotted green;
}

@media (min-width: 800px) {
  sometimes-container {
    position: relative;
  }
}

/* when the containing block of <absolute-child> is 700px+ wide */

/* custom vanilla CSS (must parse yourself) */
@--containing-block absolute-child and (min-width: 700px) {
  :--self {
    background: green;
  }
}

/* off-label browser-supported CSS (parser-free client-side) */
@supports (--containing-block(absolute-child and (min-width: 700px))) {
  [--self] {
    background: green;
  }
}

/*
  In this stylesheet, the <absolute-child> would have a green background when the browser was
  700px -> 800px wide when the containing block would be the <body> tag. But once the media
  query kicks in, the containing block becomes <sometimes-container>. The containing block
  query would be active again when the browser was 900px+ wide when <sometimes-container>
  is wide enough.
*/

I bet I could write a CSS parser plugin that would extract any @--containing-block or @supports (--containing-block()) queries, and extract the selector and media query conditions, as well as the rules inside with :--self or [--self] selectors included for scoped styles.

Since this feature can only be supported at runtime I think instead of parsing the media queries myself, to prototype it I'd re-use window.matchMedia's ability to test media queries, so for each element in the document matching one of these queries I'd locate its containing block element and resize a hidden <iframe> to the same dimensions, and then check the extracted media query syntax against the same <iframe> for all queries (changing its size each time something new needs to be measured).

Then in cases where all media queries came back true, we can populate a <style> tag in the document with a copy of the rules contained inside, and we'll add an attribute to the matching element like data-containing-block-absolute-child-min-width-700px=0 and replace :--self or [--self] in the CSS output with [data-containing-block-absolute-child-min-width-700px=0] so those rules are scoped only to the relevant elements on the page.

You could also work with CSS rules like this client-side in browsers today the @supports way, and also skip the parsing step and just look for these rules in CSSOM, and then all you need to do is split the selector and the media queries apart and feed it to the same runtime :)

Would having a custom prototype like this make it easier to explore and build use cases for a feature like this?

from element-queries-spec.

scottkellum avatar scottkellum commented on June 14, 2024

I was thinking of it a little differently. Rather than an extension of what you have in your spec, it could be something like this:

<div>
  <h1>hello world!</h1>
</div>
div {
  position: relative;
}
@element (min-width: 500px) {
  div:self {
    background: blue;
    padding: 3rem; /* ignored */
  }
  h1 {
    float: left;
    width: 50%;
  }
}
  • Contexts are defined by positioning an element. This is similar to how z-index stacked contexts work as well as top, bottom, left, right positioning works. We already have the mental model of these being contexts in CSS.
  • No box model properties can be modified within an element query on :self elements. This avoids most of the recursive issues the w3c has been complaining about.
  • Children styles are more portable to other components. The h1 defined here responds to any context that is 500px.

Additionally, I have mostly been thinking about this in the context of writing a spec for Typetura. Introducing a new property called flow or something that binds CSS keyframes to a property of a container. This binds to width, height, or scroll (similar scroll spec, that I don’t particularly like as it stands now).

flow: animation name bound to maximum minimum:0 ease:linear fill-mode:both repeat:1;

h1 {
  flow: h1 width 1200px ease-out;
}

@keyframes h1 {
  0% {
    font-size: 1rem;
    color: #000;
  }
  100% {
    font-size: 5rem;
    color: blue;
  }
}

from element-queries-spec.

scottkellum avatar scottkellum commented on June 14, 2024

Also I’m happy to have a video chat about this as I know it’s sometimes hard to talk through conceptual ideas in threads. And then bring notes back to the thread.

from element-queries-spec.

Related Issues (15)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.