New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-contain-1] do we need layout containment in a single dimension to enable container queries? #1031

Open
dbaron opened this Issue Feb 14, 2017 · 15 comments

Comments

Projects
None yet
5 participants
@dbaron
Member

dbaron commented Feb 14, 2017

One thing that came up at the extensible Web summit in Boston on Friday was a discussion of container queries.

While I'd previously suggested tying container queries to CSS containment, one thing I realized is that there will be cases where developers want to fix the width from the outside but still allow an auto height, and then do media queries on the container's width.

I haven't thought this through very much, but it seems to me that this may require a concept of layout containment in a single dimension to be exposed from containment.

@dbaron dbaron changed the title from [css-contain-1] do we need layout containment in a single dimension to enable container queries to [css-contain-1] do we need layout containment in a single dimension to enable container queries? Feb 14, 2017

@frivoal

This comment has been minimized.

Show comment
Hide comment
@frivoal

frivoal Feb 14, 2017

Contributor

Specifically, what would be needed is 1d size containment.
https://drafts.csswg.org/css-containment/#containment-size

Contributor

frivoal commented Feb 14, 2017

Specifically, what would be needed is 1d size containment.
https://drafts.csswg.org/css-containment/#containment-size

@dbaron

This comment has been minimized.

Show comment
Hide comment
@dbaron

dbaron Feb 14, 2017

Member

I think container queries require both size containment and layout containment.

Member

dbaron commented Feb 14, 2017

I think container queries require both size containment and layout containment.

@frivoal

This comment has been minimized.

Show comment
Hide comment
@frivoal

frivoal Feb 15, 2017

Contributor

I agree. What I meant is that you should be able to apply regular layout containment (which we already have) together with 1d size containment (which we don't) to get the effect you described.

So authors need both, but the WG only needs to add 1d size containment, since we already have the rest.

Contributor

frivoal commented Feb 15, 2017

I agree. What I meant is that you should be able to apply regular layout containment (which we already have) together with 1d size containment (which we don't) to get the effect you described.

So authors need both, but the WG only needs to add 1d size containment, since we already have the rest.

@css-meeting-bot

This comment has been minimized.

Show comment
Hide comment
@css-meeting-bot

css-meeting-bot Apr 19, 2017

Member

The CSS Working Group just discussed , and agreed to the following resolutions:

RESOLVED: Level 2
The full IRC log of that discussion
<fantasai> Topic:
<Florian> github topic: https://github.com/w3c/csswg-drafts/issues/1031
<fantasai> github topic: https://github.com/w3c/csswg-drafts/issues/1031
<fantasai> Florian: Next one from dbaron...
<fantasai> dbaron: This one is a big issue
<fantasai> dbaron: One of the things that a bunch of web devs really want is what they call "container queries"
<fantasai> dbaron: which basically addresses the sue case of teams that develop widgets or modules that are part of a bigger page
<fantasai> dbaron: Their developing some markup and script and whatever that gets included within a bigger page, and it will have some size
<fantasai> dbaron: The bigger page might use meida queries to e.g. switch from 3 columns to 2 colums, and widgte gets bigger though viewport got smaller
<fantasai> dbaron: If you're implementing the widget, you want to respond to the size that the widget is, not the size of the viewport
<fantasai> dbaron: Bunch of ppl want container queries that actually work, rather than do what ppl do right now which is do layout, flush, and set styles based on that
<fantasai> dbaron: Seems to me it should have some relation to containment
<fantasai> dbaron: that is, ability to do container queries should depend on some kind of ocntainment so that your insides dont depend on your outsides which depend on your insidees
<fantasai> dbaron: The next point is that sometime sppl want to do container query on their width, but have an autho height
<fantasai> dbaron: So, was thinking we want to have layout containment in only one dimension
<fantasai> dbaron: Beyond that haven't thought about it, so this is a "please design me a feature" issue
<fantasai> dbaron: This seems like a relatively high priority feature because ppl do this a lot, and do it by doing flush-restyle loops
<fantasai> Florian: If theyr'e willing to go that far, using 2D size containment is good, set it and then reset your height after you do layout
<fantasai> dbaron: Get ppl doing it for multiple parts of the page, so cycles multiple times
<fantasai> fantasai: why not just have -x -y keywords?
<fantasai> TabAtkins: Hard to define what htat means
<fantasai> eae: Maybe sets wrong expectations, that you wouldn't get same perf benefits
<fantasai> TabAtkins: True, but you do get the benefit that when your'e using resize observer you get predictable behavior and not loops
<fantasai> Florian: Seems like level 2, esp we don't have proposal yet
<fantasai> TabAtkins: This plus resize observer plus custom at-rules, I'm hoping will allow solving this use case
<fantasai> TabAtkins: Been my plan for like 10 years
<fantasai> s/10/2/
<fantasai> RESOLVED: Level 2
Member

css-meeting-bot commented Apr 19, 2017

The CSS Working Group just discussed , and agreed to the following resolutions:

RESOLVED: Level 2
The full IRC log of that discussion
<fantasai> Topic:
<Florian> github topic: https://github.com/w3c/csswg-drafts/issues/1031
<fantasai> github topic: https://github.com/w3c/csswg-drafts/issues/1031
<fantasai> Florian: Next one from dbaron...
<fantasai> dbaron: This one is a big issue
<fantasai> dbaron: One of the things that a bunch of web devs really want is what they call "container queries"
<fantasai> dbaron: which basically addresses the sue case of teams that develop widgets or modules that are part of a bigger page
<fantasai> dbaron: Their developing some markup and script and whatever that gets included within a bigger page, and it will have some size
<fantasai> dbaron: The bigger page might use meida queries to e.g. switch from 3 columns to 2 colums, and widgte gets bigger though viewport got smaller
<fantasai> dbaron: If you're implementing the widget, you want to respond to the size that the widget is, not the size of the viewport
<fantasai> dbaron: Bunch of ppl want container queries that actually work, rather than do what ppl do right now which is do layout, flush, and set styles based on that
<fantasai> dbaron: Seems to me it should have some relation to containment
<fantasai> dbaron: that is, ability to do container queries should depend on some kind of ocntainment so that your insides dont depend on your outsides which depend on your insidees
<fantasai> dbaron: The next point is that sometime sppl want to do container query on their width, but have an autho height
<fantasai> dbaron: So, was thinking we want to have layout containment in only one dimension
<fantasai> dbaron: Beyond that haven't thought about it, so this is a "please design me a feature" issue
<fantasai> dbaron: This seems like a relatively high priority feature because ppl do this a lot, and do it by doing flush-restyle loops
<fantasai> Florian: If theyr'e willing to go that far, using 2D size containment is good, set it and then reset your height after you do layout
<fantasai> dbaron: Get ppl doing it for multiple parts of the page, so cycles multiple times
<fantasai> fantasai: why not just have -x -y keywords?
<fantasai> TabAtkins: Hard to define what htat means
<fantasai> eae: Maybe sets wrong expectations, that you wouldn't get same perf benefits
<fantasai> TabAtkins: True, but you do get the benefit that when your'e using resize observer you get predictable behavior and not loops
<fantasai> Florian: Seems like level 2, esp we don't have proposal yet
<fantasai> TabAtkins: This plus resize observer plus custom at-rules, I'm hoping will allow solving this use case
<fantasai> TabAtkins: Been my plan for like 10 years
<fantasai> s/10/2/
<fantasai> RESOLVED: Level 2
@ausi

This comment has been minimized.

Show comment
Hide comment
@ausi

ausi Apr 19, 2017

I would really like this feature to help container query scripts to solve the recursion issue. But is size/layout containment in one dimension even possible?

Take, for example, the following structure (assuming that size-x would be the value for containment across the X axis):

<style>
	.wrapper { height: 100px; overflow-y: auto }
	.component { contain: size-x }
</style>
<div class="wrapper">
	<div class="component">
		Content that grows in height via a container query script
		when the width gets wider.
	</div>
</div>

In an edge case this could still lead to an endless loop I think: The width of .component depends on the content-with of .wrapper and the content-width of .wrapper depends on the height of .component (because of the scrollbar). This means that the width of .component would still depend on its contents even though contain: size-x is set.

ausi commented Apr 19, 2017

I would really like this feature to help container query scripts to solve the recursion issue. But is size/layout containment in one dimension even possible?

Take, for example, the following structure (assuming that size-x would be the value for containment across the X axis):

<style>
	.wrapper { height: 100px; overflow-y: auto }
	.component { contain: size-x }
</style>
<div class="wrapper">
	<div class="component">
		Content that grows in height via a container query script
		when the width gets wider.
	</div>
</div>

In an edge case this could still lead to an endless loop I think: The width of .component depends on the content-with of .wrapper and the content-width of .wrapper depends on the height of .component (because of the scrollbar). This means that the width of .component would still depend on its contents even though contain: size-x is set.

@frivoal frivoal removed the css-contain-1 label Apr 19, 2017

@gregwhitworth

This comment has been minimized.

Show comment
Hide comment
@gregwhitworth

gregwhitworth Apr 6, 2018

Contributor

@ausi containment only works on the box that it is applied to; so, in your scenario, you're only containing size-x for .component. Thus whatever size-x is defined to do will occur for its content and will then propagate the resulting geometry to .wrapper. Regarding scrolling, it this geometry results in the height being over 100px then you re-layout .wrapper with the scrollbar in place (this is how scrollbars work today)

Contributor

gregwhitworth commented Apr 6, 2018

@ausi containment only works on the box that it is applied to; so, in your scenario, you're only containing size-x for .component. Thus whatever size-x is defined to do will occur for its content and will then propagate the resulting geometry to .wrapper. Regarding scrolling, it this geometry results in the height being over 100px then you re-layout .wrapper with the scrollbar in place (this is how scrollbars work today)

@ausi

This comment has been minimized.

Show comment
Hide comment
@ausi

ausi Apr 6, 2018

Regarding scrolling, if this geometry results in the height being over 100px then you re-layout .wrapper with the scrollbar in place

But wouldn’t this re-layout update the width of .component?

ausi commented Apr 6, 2018

Regarding scrolling, if this geometry results in the height being over 100px then you re-layout .wrapper with the scrollbar in place

But wouldn’t this re-layout update the width of .component?

@gregwhitworth

This comment has been minimized.

Show comment
Hide comment
@gregwhitworth

gregwhitworth Apr 6, 2018

Contributor

@ausi Yes - but that is how it works today because in scrollbar auto we don't know if we should show one or not, so if you need one we have to do a second pass. Now, based on the containment set you may NOT get to 100px so you won't have that relayout, but again this isn't new.

Contributor

gregwhitworth commented Apr 6, 2018

@ausi Yes - but that is how it works today because in scrollbar auto we don't know if we should show one or not, so if you need one we have to do a second pass. Now, based on the containment set you may NOT get to 100px so you won't have that relayout, but again this isn't new.

@ausi

This comment has been minimized.

Show comment
Hide comment
@ausi

ausi Apr 6, 2018

The relayout would change the width of .component, so ultimately the width of .component depends on it’s contents even though contain: size-x is set.

As far as I understand it, this means that implementing contain: size-x in a browser is impossible, because it cannot be assured that the size in one dimension doesn’t respond to changes to the size in the other dimension.

ausi commented Apr 6, 2018

The relayout would change the width of .component, so ultimately the width of .component depends on it’s contents even though contain: size-x is set.

As far as I understand it, this means that implementing contain: size-x in a browser is impossible, because it cannot be assured that the size in one dimension doesn’t respond to changes to the size in the other dimension.

@gregwhitworth

This comment has been minimized.

Show comment
Hide comment
@gregwhitworth

gregwhitworth Apr 6, 2018

Contributor

@ausi I mean it's a valid wrinkle, but personally, I think authors would be ok with this type of "two pass" layout as they normally would want the scrollbar to appear, and probably aren't even noticing (in most cases) that two passes are required. As a result, you can still honor the constraint but only once you've answered the question of "does it have scrollbars?" or not. @frivoal @dbaron thoughts?

Contributor

gregwhitworth commented Apr 6, 2018

@ausi I mean it's a valid wrinkle, but personally, I think authors would be ok with this type of "two pass" layout as they normally would want the scrollbar to appear, and probably aren't even noticing (in most cases) that two passes are required. As a result, you can still honor the constraint but only once you've answered the question of "does it have scrollbars?" or not. @frivoal @dbaron thoughts?

@ausi

This comment has been minimized.

Show comment
Hide comment
@ausi

ausi Apr 6, 2018

I think the “two pass” layout for scrollbars is basically OK for authors. The problem arises if a container query script comes into play.

The spec for contain: size says:

Its primary benefit on its own is that tools which want to lay out the containing element’s contents based on the containing element’s size (such as a JS library implementing the "container query" concept) can do so without fear of "infinite loops", …

The same “no infinite loops” benefit would be required for contain: size-x, but this is impossible I think. And without this benefit the feature would be useless.

ausi commented Apr 6, 2018

I think the “two pass” layout for scrollbars is basically OK for authors. The problem arises if a container query script comes into play.

The spec for contain: size says:

Its primary benefit on its own is that tools which want to lay out the containing element’s contents based on the containing element’s size (such as a JS library implementing the "container query" concept) can do so without fear of "infinite loops", …

The same “no infinite loops” benefit would be required for contain: size-x, but this is impossible I think. And without this benefit the feature would be useless.

@frivoal

This comment has been minimized.

Show comment
Hide comment
@frivoal

frivoal Apr 7, 2018

Contributor

I wonder if this can be solved by making size-x work only when there's a specified width that does not depend on the parent (i.e. no auto, no available, no fit-content, no percentage). This certainly limits the situations in which you can use size-x, but if these are cases which would not work anyway, I think that leave us with cases where it does. Not sure it is still sufficiently useful though.

Alternatively, since I believe the problem is exclusively caused by an ancestor having auto scrollbars, maybe that's what we fix: if an overflow:auto element has a descendant with 1d size containment (2d also? not sure), then the scrollbar must be always visible, regardless of whether there is actual overflow or not (with an allowance for overlay scrollbars).

Contributor

frivoal commented Apr 7, 2018

I wonder if this can be solved by making size-x work only when there's a specified width that does not depend on the parent (i.e. no auto, no available, no fit-content, no percentage). This certainly limits the situations in which you can use size-x, but if these are cases which would not work anyway, I think that leave us with cases where it does. Not sure it is still sufficiently useful though.

Alternatively, since I believe the problem is exclusively caused by an ancestor having auto scrollbars, maybe that's what we fix: if an overflow:auto element has a descendant with 1d size containment (2d also? not sure), then the scrollbar must be always visible, regardless of whether there is actual overflow or not (with an allowance for overlay scrollbars).

@ausi

This comment has been minimized.

Show comment
Hide comment
@ausi

ausi Apr 7, 2018

I wonder if this can be solved by making size-x work only when there's a specified width that does not depend on the parent (i.e. no auto, no available, no fit-content, no percentage). … Not sure it is still sufficiently useful though.

This would work I think, but it would not be useful for container query scripts anymore.

I believe the problem is exclusively caused by an ancestor having auto scrollbars

Unfortunately, I don’t think scrollbars are the only case this could happen. Take for example this code of a contain: size-y example (CodePen):

<div class="parent">
  <div class="inner">
    <div class="child"></div>
  </div>
</div>
<style>
  * { box-sizing: border-box }
  .parent {
    float: left; /* this makes the width depend on its contents */
    height: 100px;
  }
  .inner {
    padding-top: 10%; /* this percentage is relative to the width */
    height: 100%;
  }
  .child {
    height: 100%;
    contain: size-y; /* would not work in this case */
  }
</style>

(2d also? not sure)

Two-dimensional contain: size is not affected because its specified behavior is “When laying out the containing element, it must be treated as having no contents.”

ausi commented Apr 7, 2018

I wonder if this can be solved by making size-x work only when there's a specified width that does not depend on the parent (i.e. no auto, no available, no fit-content, no percentage). … Not sure it is still sufficiently useful though.

This would work I think, but it would not be useful for container query scripts anymore.

I believe the problem is exclusively caused by an ancestor having auto scrollbars

Unfortunately, I don’t think scrollbars are the only case this could happen. Take for example this code of a contain: size-y example (CodePen):

<div class="parent">
  <div class="inner">
    <div class="child"></div>
  </div>
</div>
<style>
  * { box-sizing: border-box }
  .parent {
    float: left; /* this makes the width depend on its contents */
    height: 100px;
  }
  .inner {
    padding-top: 10%; /* this percentage is relative to the width */
    height: 100%;
  }
  .child {
    height: 100%;
    contain: size-y; /* would not work in this case */
  }
</style>

(2d also? not sure)

Two-dimensional contain: size is not affected because its specified behavior is “When laying out the containing element, it must be treated as having no contents.”

@frivoal

This comment has been minimized.

Show comment
Hide comment
@frivoal

frivoal Apr 9, 2018

Contributor
Contributor

frivoal commented Apr 9, 2018

@ausi

This comment has been minimized.

Show comment
Hide comment
@ausi

ausi Apr 9, 2018

However, if you add box-sizing: border-box on .inner, then there is an effect on .inner's content height, and we do have a problem. Damn.

Yeah, I forgot to set the box-sizing in my example (it was only in the linked CodePen).

Unlike scrollbars, I don't see any simple way to fix that one.

Neither do I. I would really love this feature, but the more I think of it, the more impossible it seems to me.

ausi commented Apr 9, 2018

However, if you add box-sizing: border-box on .inner, then there is an effect on .inner's content height, and we do have a problem. Damn.

Yeah, I forgot to set the box-sizing in my example (it was only in the linked CodePen).

Unlike scrollbars, I don't see any simple way to fix that one.

Neither do I. I would really love this feature, but the more I think of it, the more impossible it seems to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment