Skip to content
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-flexbox] Absolute Positioned Elements in Flex Containers Removes Common Layout Patterns #401

Closed
jlukic opened this issue Aug 12, 2016 · 14 comments

Comments

@jlukic
Copy link

jlukic commented Aug 12, 2016

https://drafts.csswg.org/css-flexbox/#abspos-items

Currently Flexbox spec does not allow absolutely positioned elements inside a flex container to preserve their calculated position when using top: auto; or left:auto; (its initial value).

Here's an example of this behavior in both flex and normal containers.
https://jsfiddle.net/91tn25zn/

Outside of flex containers using auto positioning values behaves this way, so this is new behavior added in flex.

This behavior inside flex containers removed a very important method for positioning elements in CSS, allowing elements to exist outside of page flow but preserve their calculated positions. For example this breaks all vertical dividers in Semantic UI which represents a common design pattern of adding elements which do not participate in layout, but are used for styling based on their rendered position.

@cbiesinger
Copy link

@fantasai
Copy link
Collaborator

I'm confused. Why is this divider absolutely-positioned? Why not be in-flow?

@jlukic
Copy link
Author

jlukic commented Aug 17, 2016

So that the dividers dont affect layout. In this case, the spacing between grid columns should remain the same regardless of whether user elects to add vertical dividers. (Not jump over by 1px)

Since grid columns are frequently percentage based, the additional pixel will also break the percentage ratios (i.e. 25% + 25% + 25% +25% + 1px).

@cbiesinger
Copy link

You can give them a zero width and just let it overflow

@jlukic
Copy link
Author

jlukic commented Aug 17, 2016

And in the case that overflow or width is necessary for styling? For example background color in the divider case is filled based on width. Using alternatives like border-width will also cause it to have width that affects layout.

And also, why exactly should left: auto operate differently inside a flex container?

@jlukic
Copy link
Author

jlukic commented Dec 27, 2016

What are the chances that revising auto positions in flex containers can be at least discussed by the CSS-WG?

@rachelandrew
Copy link
Contributor

@jlukic do you have other use cases in addition to this vertical divider one? I'm wondering if the real use case is the ability to place the vertical divider without changing layout (even if that were achieved another way). Or are there other cases in the wild we could add to the issue?

@jlukic
Copy link
Author

jlukic commented Feb 21, 2017

The general reason I'd advocate for this change is that it is important left: auto; and top: auto behave consistently regardless of parent container so that component authors can write generic code that works without having to know where it is placed.

The argument for the utility of absolutely positioned elements placed with auto position is a bit broad, but I'll go ahead and make the case for times I'd use this pattern

Elements might need absolute and top/left:auto when

  • Element needs to be positioned "in layout", aka respective to its position in normal content flow but should not affect surrounding content position. (Most often these are decorators like layered backgrounds, dividers, bevels, etc)

Some reasons for needing this pattern:

Element (requires layout as described above and)

  • Is positioned relative to the parent element's padding
  • Is positioned relative to a sibling element's margin
  • Should shift in position with line breaks in inline block or floated items
  • Should position differently based on text-align or align-items
  • Other elements use exact percentages in a non-flex container, i.e. 3 column (33.33%) and element width is fixed (i.e. specified in px) and should not affect percentages
  • Needs to overlap preceding/previous content without affecting its position
  • Needs to be represented as a percentage of its parent containers size
  • Need to be animated as a separate layer which should not cause the surrounding content to jump in position between display: none and visible

@fantasai
Copy link
Collaborator

It's a bit easier to describe where the item "would have been" in block layout than in flexbox. Some of the complicating factors are the fact that flex layout can wrap -- the abspos element will arbitrarily associate itself with the previous element rather than the next one after the break -- and the way that spacing works -- if the author specifies 'space-around', where does the item go? Before the space? After it? Halfway in between? What about at the edges of the flex container (rather than between two items)? Should it increase the spacing?

In implementations that had the abspos take a position in the flow, the existence of the abspos affected layout, and that's not something that seemed appropriate. So we tried to simplify the static position calculation in order to get a result where it really didn't affect layout and ended up here, which isn't ideal for your use cases. Possibly if we'd understood your problem here sooner, Tab and I would have pushed harder to solve the 'space-around' case and keep the static position as the "hypothetical position", but I suspect it's too late to make such a change at this point. (I also have no idea how one would do the equivalent thing in Grid, and we do want to keep Grid and Flexbox consistent.)

But let's go back to Christian's suggestion--it seems to me that would get you what you want (except in the 'space-around' cases, which were previously broken anyway). If your item itself needs a width, there are two ways to handle it: if the border-box width is known, set a negative margin equivalent to that. If not, wrap it in a zero-sized element and let it overflow that element. This technique should also work in other layout modes as well--particularly the latter one, if the actual element is an abspos inside the wrapper then it shouldn't affect margin collapsing, either.

Anyway, nobody's commented here except Christian so I'll Agenda+ to see if anyone in the WG has thoughts.

@gregwhitworth
Copy link
Contributor

We also discussed static position (of flex/grid items) in issue #440, and @cbiesinger pointed out the desire to not modify the calculation of static position due to compat concerns and I strongly agree here. In the same spirit I would push back on any change especially when the given use case can be achieved.

@astearns
Copy link
Member

We resolved on the call today to not take this change, reaffirming our previous resolution to allow the new layout systems to have new static position behavior. It's unclear how it would even be possible to maintain the old static position behavior given how flexbox layout works, and it would be at least twice as complex to maintain the old behavior in grid.

@jlukic
Copy link
Author

jlukic commented Mar 22, 2017

Prescriptivism is alive!

@astearns
Copy link
Member

astearns commented May 2, 2017

@jlukic we've recorded your response to the issue in our "Disposition of Comments" for publishing a new version of the spec: https://drafts.csswg.org/css-flexbox-1/issues-cr-20160526#issue-18.

If you are certain that we've made a technical error, you can register a "Formal Objection" here as a comment. This will flag this issue as one where the director should closely review the WG's decision. If you do, please summarize your technical argument for the director's consideration.

@svgeesus
Copy link
Contributor

@jlukic if you do not wish to register a formal objection, please let us know that you are able to accept the WG resolution.

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

No branches or pull requests

8 participants