cq-usecases icon indicating copy to clipboard operation
cq-usecases copied to clipboard

Use case: user-resizable elements

Open eeeps opened this issue 8 years ago • 4 comments
trafficstars

The main use-case in the doc, right now, is modular components that can appear in a variety of different contexts. It’s a real drag to write and maintain different media queries for each potential context.

If elements are user-resizable – e.g., textarea by default or anything with a CSS resize != none – there’s no way to work out an element’s size from the size of the viewport; media queries become useless.

A couple of use cases that come to mind:

  • a resizable textarea that adjusts its typography in response to its size, in order to keep line lengths nice and readable, like https://ia.net/topics/bringing-responsiveness-the-app-world/
  • user-arrangeable tool palettes (e.g. a color picker that goes from HSV sliders when short, to an HSV wheel when tall)

eeeps avatar Jun 05 '17 16:06 eeeps

I think the texarea example would be an element (not container) query because the styles would depend on the width of the element itself. This could result in the recursion issue very quickly, like:

textarea { resize: horizontal }
textarea:media(min-width: 100px) {
	color: red;
	width: 90px;
}

It should only work if a parent element is resizable I think.

ausi avatar Jun 08 '17 07:06 ausi

Yeah, in that case, you’d have to make a resizable wrapper, and prevent resizing directly on the textarea, like this: https://codepen.io/eeeps/pen/YQwyPz?editors=1100

eeeps avatar Jun 08 '17 23:06 eeeps

Here's are demos of the “make the font size 1.5em when the textarea element is wider than 400 pixels“ functionality in EQCSS, Selectory, reproCSS globally, and reproCSS using the container queries mixin:

<!-- EQCSS -->
<textarea id=eqcss></textarea>
<style>
  @element #eqcss and (min-width: 400px) {
    $this {
      font-size: 1.5em;
    }
  }
</style>

<!-- CSSplus/Selectory -->
<textarea id=selectory></textarea>
<style>
  #selectory[test='this.offsetWidth >= 400'] {
    font-size: 1.5em;
  }
</style>

<!-- ReproCSS -->
<textarea id=reprocss></textarea>
<style process=auto>
  ${document.querySelector('#reprocss').offsetWidth >= 400 && '#reprocss'} {
    font-size: 1.5em;
  }
</style>

<!-- ReproCSS + Container Query mixin -->
<textarea id=containerQueries></textarea>
<style process=auto>
  ${container('#containerQueries', 'this.offsetWidth >= 400', '', 'font-size: 1.5em')}
</style>

<style>
  textarea {
    display: block;
    resize: both;
  }
</style>
<script src=http://eqcss.com/EQCSS.js></script>
<script src=http://csspl.us/selectory.js></script>
<script src=https://tomhodgins.github.io/reprocss/mixins/container-queries.js></script>
<script src=https://tomhodgins.github.io/reprocss/reprocss.js></script>

So that's 4 ways to express the same logic. I feel like using :media() for functionality that relates to the width of an element is kind of a misnomer. Maybe somebody can explain how that's "media" but it's not very logical to me, I'd interpret div:media(min-width: 100px) as some kind of sugar for @media (min-width: 100px) { div {} }

tomhodgins avatar Jul 20 '17 18:07 tomhodgins

Great example of a menu panel that the user can open and close, which adjusts the size of everything else on the page: https://github.com/w3c/csswg-drafts/issues/3852#issuecomment-493683805

eeeps avatar May 18 '19 15:05 eeeps