-
Notifications
You must be signed in to change notification settings - Fork 24
Element Query race conditions #9
Comments
I know this falls under the technical aspects of EQ's, which we're nowhere near yet, but is there some sort of precedent or compatibility issue in which saying that CSS properties that trigger layout will be ignored in element queries? (Though I'd assume compatibility is moot since the query itself will be ignored entirely similar to the way in which media queries are ignored on older browsers.) |
That makes it worthless, since the whole point is responding to the size of the container, and often sizing yourself appropriately. |
Or did you mean, for example, ignoring setting of width of an element in a My opinions: To me that makes sense to avoid recursive element query problems. But setting the width on an inner child element is perfectly valid.
|
@jehoshua02, that is what I was thinking of. Clearly it needs to be fleshed out more, but I wanted to get the ball rolling on how this might be handled, as it's probably one of the bigger technical issues EQ's will encounter. |
I was thinking of this today actually - then found this issue. As a quick idea I thought you could perhaps block properties of the element with the query that matched the query. For example (I picked the most non css syntax possible to show the example not the code):
So when the element became over 800 wide only red would be applied to the div but the img would become 150px wide. I'm sure you are likely to tell me very quickly however that inner elements matter just as much as will cause reflow which could cause text to force the parent to be wider for example. Perhaps however that could be mitigated with a bottom up recalculation of dom nodes of an elements child nodes to reduce the chance of an infinite loop chain effect. Also I suggest at any point the width of the child nodes causing the parent element to resize outside of the media query bounds from within the same rule then the execution stops and the parser treats it as invalid so never is ran again. This also would need a mapping of rules that are blocked like max-width bans any width based rule etc. I'm not suggesting this is right just thought I would share my initial thoughts on the issue. |
What we've discussed in the latest call was that having an element's style dependent on that element's style is circular by definition, and not something we should be supporting. What we're after is styling elements based on properties of a "special" containing element (which dimensions can't be impacted by its descendants). |
@yoavweiss I read that in another post somewhere. My initial worry was does that scale if every element was 'special'. However that certainly does simplify the problem. |
I'm not a fan of making every element 'special'. See https://www.youtube.com/watch?v=A8I9pYCl9AQ I think that we need EQs to serve as module boundaries, so you can develop things relative to the module. If you really must have an element react to its own dimensions, add a wrapper around it, and declare the wrapper as "special". |
Heh yeah that's why I wasn't calling it special. I'm thinking of every web component able to have this behaviour if it chose. In my templates instead of writing html I aim to just write in application specific web components where the components contain the html itself. Like you say these are completely self contained modules that the template author has power of the box size and the parameters passed in. This might be a little extreme even for fans of web components however from what I have found it removes the worry of when to write web components and when to write markup. Anyway hopefully that demonstrates why I think 'special' is bad and likely people will treat it as the norm. |
This might be off-topic, but thinking about Element Queries I assume that the "components" aren't really self contained, but that they inherit CSS of the rest of the website. That's the general consensus right? The way Jonathan describes this makes it sound a bit like some sort of iframe with self contained HTML & CSS. Regarding size: Setting width must still be possible at least in percentages. I could see some cases in which setting a width, or max-width, yourself (if you really need an element to be a certain size, which is probably when it is in a certain spot in the website like a sidebar or footer) could be what you want, although this probably isn't the best solution in that case. If an element is a certain size, it's very clear which EQ should be applied. That's simple and expected behaviors, but if any element within that element makes the element bigger than potentially other EQ's might be applied. Is it too short sighted that this is on the developer? Just like floats going haywire now? |
@PaulSpr that's a great question and I have seen the feature mentioned as an iframe. This is similar to the behaviour of shadow dom. This is how I was thinking but also like the shadow dom I was expecting the parent to have control over what was exposed from the shadow dom. The second issue is that yes floats can go haywire but they couldn't cause a potential infinate loop of changing widths. |
This is a case I think I would ignore and leave it up to developers to not do dumb things. Consider this: .my-element (width < 500) {
width: 500;
} Doing something like this is silly and no web developer should ever do something like this. I wouldn't waste any time writing guards against stupid stuff like this into the browser or spec. |
@jehoshua02 I'm a fail hard sort of programmer too but user agents could not just crash though so some error handling would have to happen. |
I did some checks with a browser inspector. If you change the width of the body it won't switch apply extra media queries of you exceed your breakpoints. This got me wondering. A solution is to match EQ to the dimensions the element would logically have if it didn't apply any weird forces, like a block element with It's also problematic from when looking at height, that is almost always determined by the forces within an element pushing it's bottom border down. Maybe treat width and height differently? And what if for some reason your element has negative margins on the left and right? Argh, headaches. This stuff is hard. |
@jehoshua02 Sorry, but that's impossible. Just saying "don't do it" doesn't work; you still need to define what it does. After all, it'll do something - if it crashes, that's exploitable, so browsers wouldn't crash; if it doesn't crash, then it has some particular (undefined) effect, and devs will end up depending on that behavior. Since it's undefined, browsers will initially do different things, and they'll end up having to reverse-engineer each other to match behavior, and everything will be terrible, and lo fire shall rain down from the heavens and blast this damned earth. Or we can avoid all of that by defining what it means (or defining that it doesn't work at all). |
Nope, doesn't work either. :/ As you note, children also have an effect - that's why the EQ container is going to have to ignore its children for the purpose of determining its own dimensions. But also, any communication channel opens up the possibility for loops. Check this example for toggle-* properties. You can widen the loop to include two or more property/selector combos, so that no individual style rule violates the "no related properties inside a block with this selector" rule, but all combined they do. That is, imagine two properties, :foo {
bar: on;
}
:bar {
foo: off;
}
* {
foo: on;
bar: off;
} If Avoiding circularity in declarative languages is a tricky business. |
@tabatkins I fear an example like this would come along. Does my other comment around this feature being more than just a special case cause issues? My other comment around allowing the child to impact the parent would be possible so long as the user agent rejects the side impacts of applying further queries within this query. I get however that's potential to be messy as you stated however. |
@tabatkins Okay, okay, you're right. We gotta define what it'll do. |
Wait, go back to the “fire rain” thing? That doesn’t sound so bad. I mean, I’ve seen worse standards. |
I don’t think you would have raw declarations inside the query. It would need rules with selectors, just like media queries. So, more like this:
At which point, the fact that you used |
So in other words, since |
What do you mean as if the children had zero width? But even assuming we accept those constraints, you still not escape circularity: .container { font-size: 500px; }
.container (height > 200px) {
font-size: 10px;
} The above would cause circularity even if we apply the font-size rules on a descendant. |
What seems to often be missed in this circularity argument with element/container queries is that CSS ALREADY HAS THIS PROBLEM. This is easily demonstrated. https://codepen.io/matthewdean/pen/LdvVZZ Hover your mouse over the word "out". At least in Chrome, you will get an infinite resizing loop. So I don't understand why spec authors, developers, and browser vendors get so stuck on the issue of circularity. It exists and it has always existed from day 1 in CSS. Any selector state which can change the appearance of an element which changes its behavior which resets its state can have this happen. No one was complaining about circularity in
No, we don't. Why? No one defined what
|
Hi, @matthew-dean! My current understanding is,
I've never created a |
🤔 Okay fair enough. I understand that it's not exactly equivalent. Pardon my frustration. Like every CSS developer, I'm just frustrated that container/element queries don't already exist; which is not a statement against anyone in particular. I just feel like the impetus to implement is just greater than the potential roadblock of circularity. And I also feel like circularity is not, as far as problems go, that big of a challenge to solve. If there's some particular behaviour that is more intuitive and desirable than the layout engine rendering nothing because a layout loop is detected, then that seems solvable. Incidentally, wouldn't this be more akin to Let me channel my frustration. Infinite loops are probably not the answer. Instead, how can I help make container queries happen? |
Hi @matthew-dean - I share your frustration, which is why I got involved in this. As this repo is about getting the use-cases document off the ground, if you’d like to help, you could have a look through the open issues and see where you could contribute. Also, it seems to me the document as it stands lacks a wide variety of use-cases[1], so you could maybe document the actual problems you’re facing where container queries are the solution? Maybe create some simplified code-pens or similar demonstrating these problems and post them to a relevant issue (or create a new one)? Cheers
|
I wrote up the canonical reason why this isn't true over on the CSSWG wiki: https://wiki.csswg.org/faq#selectors-that-depend-on-layout |
@andykirk Thanks! Will do as soon as I have time. |
@davatron5000 is cataloging the CSS properties that may trigger race conditions for element queries. I’ve put them into a list to share with you:
https://gist.github.com/jonathantneal/5996a3e9b33d7a6afa5d
The text was updated successfully, but these errors were encountered: