[csswg-drafts] [css-conditional] Applying styles based on an elements size (@media for elements) (#3852)

mtom55 has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-conditional] Applying styles based on an elements size (@media for elements) ==
For: https://drafts.csswg.org/css-conditional-3/

Although it's possible this might need to be applied to a different part of the specification.

**PROBLEM:**
It is possible to apply styles to an element based on the viewports size, but not to the elements size.  


Take the following example:
```html 
<!doctype html>
<html>
    <body>
        <div class="container">
            <div class="menu">
                MENU CLOSED
            </div>
            <div class="main">
                SomeText
            </div>
        </div>
    </body>
</html>
```
```css
* { 
    box-sizing: border-box; 
    margin: 0;
}
html, body { height: 100%;}

body {
    display: flex;
    flex-direction: column;
}

.container {
    flex: 1;
    
    display: flex;
}

.menu {
    width: 100px;
    border: 1px solid red;                 
    margin: 20px;
    padding-top: 20px;
    color: red;
    font-size: 18px;
    text-align: center;
}

.main {
    flex: 1;
    
    margin: 20px;
    padding: 20px;

    border: 1px solid blue;
    text-align: right;
    font-size: 80px;
}

@media (max-width: 500px) {
    .main {
        color: green;
        font-size: 20px;
    }
}
```

![image](https://user-images.githubusercontent.com/11502425/56409824-5071a480-62ad-11e9-995e-06c632404a57.png)

Using a media query I can change it so that as the width of the viewport shrinks we can reduce the size of the text so that it fits like so:

![image](https://user-images.githubusercontent.com/11502425/56409829-58c9df80-62ad-11e9-9211-6e768124faf1.png)

but if the we expand or contract the menu (i.e. if the user presses a button and we use javascript to change the width of the menu), there is no way currently in CSS to change the style based on an elements size.


![image](https://user-images.githubusercontent.com/11502425/56409855-7303bd80-62ad-11e9-83ea-e45552d2a179.png)

Currently we have to use ResizeObserver (or mutation observer in browsers that don't support it) to monitor the size of the element and then remove and add a CSS class which we can then use to apply the style.


**POSSIBLE SOLUTIONS:**

A possible solution would be to add a CSS selector like:
```css
.main::conditional(max-width: 500px) {
    color: green;
    font-size: 20px;
}
```

As a minimum viable spec, it would be nice to support max-width, min-width, max-height, min-height but it could be expanded to include all the current media options.. for example:
```css
.main::conditional((min-width: 500px) and (orientation: landscape)) {
    color: green;
    font-size: 20px;
}

.main::conditional(min-width: 500px) .childElement{
    color: pink;
}
```

**CONSIDERATIONS:**
The widths and heights of each element would need to be calculated first.  Then the conditional arguments would need to be run through altering the widths and heights of the elements.  

The issue with running it in javascript, is that you can get a flickering as the ResizeObserver will get triggered on every change and the css you are applying can break the condition (i.e. by changing the width).

By moving this into CSS it's not longer an issue because the resizing only happens once.

**USAGE:**
I've discussed this in depth with a large group of web-developers and we think this would be very useful, however the syntax and mechanics are not quite obvious. 


Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3852 using your GitHub account

Received on Friday, 19 April 2019 06:21:48 UTC