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] flex-wrap-layout property for wrapped flex lines #8252

Open
artit91 opened this issue Dec 21, 2022 · 10 comments
Open

[css-flexbox] flex-wrap-layout property for wrapped flex lines #8252

artit91 opened this issue Dec 21, 2022 · 10 comments

Comments

@artit91
Copy link

artit91 commented Dec 21, 2022

I know that CSS grids are a good alternative to tables but not available in react-native/yoga. A layout property for multiple lines would solve a lot of problems and make CSS grids less overused. CSS grids also tend to not scale well because you need to define everything on the parent.

Currently it's not possible to render a simple dynamic bar chart with X and Y axis without using tables or grids. A bar chart has nothing to deal with tables or grids.

I'm thinking about something like this:

flex-wrap-layout: tabular

Currently dealing with tables a bit of magic to achieve flex-like layout.

You need something like this:

table {
  width: 100%;
  table-layout: fixed;
}
td {
   width: 100px;
}
td:last-child {
   width: 100%;
}

This gets very complicated very quickly.

The corresponding OpenAI discussion. Are we there yet?
image

@artit91 artit91 changed the title [flexbox] flex-layout property for wrapped flex lines [css-flexbox] flex-layout property for wrapped flex lines Dec 21, 2022
@artit91 artit91 changed the title [css-flexbox] flex-layout property for wrapped flex lines [css-flexbox] flex-wrap-layout property for wrapped flex lines Dec 21, 2022
@Loirooriol
Copy link
Contributor

I don't understand what flex-wrap-layout: tabular is supposed to do, nor what kind of bar chart you want. Flexbox and tables are entirely different layout models, so the text in the image doesn't really make sense to me. Sizing flex items according to their contents is what happens by default, and growing them to fill the available size of the container is what happens when you use flex-grow.

Also, if CSS grids are the right tool but your problem is that react-native/yoga doesn't support grid, then how would flex-wrap-layout: tabular help if react-native/yoga doesn't support it either? Shouldn't you request react-native/yoga to just support grid instead? I don't know react-native/yoga so I may be missing the point.

@artit91
Copy link
Author

artit91 commented Dec 22, 2022

The screenshot was just joke. I agree it's pretty bad.

Many people requested grids in yoga but it has never been priority and I understand why. Flex layout is very fast and almost feature complete apart from defining the wrap behavior.

I believe as yoga based layout is taking over the internet, this is the best platform to propose changes to spec. People who work on yoga, often work on web as well. See react native web.

The current wrap behavior is set in stone, once I questioned the existence all together because the layout definitions were quirky but we reached that point that it's not just required, it became essential leading to a lot of hacky unreadable code. The wrapping flows the containers as text into multiple lines and that behavior is rarely or not used at all. When wrapping is used, the expected result is always some kind of simple grid. Implementing it is fairly straightforward, getting the max-width in every row and apply to the n-th column when the flex direction is row, when column, getting the max-height in every column. Countless codebases are using this to "hotfix" flex based layouts.

@SebastianZ
Copy link
Contributor

Currently it's not possible to render a simple dynamic bar chart with X and Y axis without using tables or grids.

This use case actually doesn't sound like it should be solved using Flexbox either but rather a case for SVG. And there are already plenty libraries out there that allow you to create charts.

Though if you want to solve this using Flexbox and if I understand your use case correctly, then I assume the flex value of wrap-before and wrap-after might come in handy. (Though those properties are not implemented anywhere yet, unfortunately.)

But even without those it is fairly easy to create a chart in Flexbox. See https://jsfiddle.net/SebastianZ/n52jk6cd/.

If the current possibilities are not suitable for your use case, please provide an example of what you want to achieve and clarify the issue you are having to get what you want.

Sebastian

@artit91
Copy link
Author

artit91 commented Dec 26, 2022

Currently it's not possible to render a simple dynamic bar chart with X and Y axis without using tables or grids.

This use case actually doesn't sound like it should be solved using Flexbox either but rather a case for SVG. And there are already plenty libraries out there that allow you to create charts.

Though if you want to solve this using Flexbox and if I understand your use case correctly, then I assume the flex value of wrap-before and wrap-after might come in handy. (Though those properties are not implemented anywhere yet, unfortunately.)

But even without those it is fairly easy to create a chart in Flexbox. See https://jsfiddle.net/SebastianZ/n52jk6cd/.

If the current possibilities are not suitable for your use case, please provide an example of what you want to achieve and clarify the issue you are having to get what you want.

Sebastian

Hi Sebastian,

I meant a simple bar graph like this: (Yes I use SVG and Yoga)

image

Both the size of the x and y axis can be dynamic with a max width/height. Column gap is used between the bar items.

The bars fill the remaining area.

wrap-before wrap-after would not solve the wrap issue but it definitely makes the implementation cleaner.

The screenshot above is "hacked". I use absolute positioning for the X axis and "line height" amount of padding bottom.

When I lay out the graph using flex-wrap, the width of the first "cell" of the second line does not match the Y axis'. It needs to be hardcoded.

I also understand that it's fairly easy with CSS Grids (https://codepen.io/artit91/pen/oNMjOMg).

Thanks,
Attila

@Loirooriol
Copy link
Contributor

I still have no idea of what flex-wrap-layout: tabular would do. Please provide some examples with the hypothetical HTML and CSS using flex-wrap-layout: tabular, and and image with the behavior that would result from that. It seems to me that you can create such chart using either flex or grid, without needing flex-wrap-layout: tabular.

@artit91
Copy link
Author

artit91 commented Dec 27, 2022

I still have no idea of what flex-wrap-layout: tabular would do. Please provide some examples with the hypothetical HTML and CSS using flex-wrap-layout: tabular, and and image with the behavior that would result from that. It seems to me that you can create such chart using either flex or grid, without needing flex-wrap-layout: tabular.

I think the best would be if I polyfill it. I will be back.

@artit91
Copy link
Author

artit91 commented Feb 11, 2023

I still have no idea of what flex-wrap-layout: tabular would do. Please provide some examples with the hypothetical HTML and CSS using flex-wrap-layout: tabular, and and image with the behavior that would result from that. It seems to me that you can create such chart using either flex or grid, without needing flex-wrap-layout: tabular.

Hi everyone, sorry for the late reply.

I created a very simple example to show what a tabular layout could do to wrapped flex items:

The graph using CSS Grids:
https://codepen.io/artit91/pen/oNMjOMg

The graph using flex-wrap-layout: tabular:
https://codepen.io/artit91-the-solid/pen/PoBMOer

I hope this will clear things up.

You can change the value of --flex-wrap-layout: tabular to something else to see how the layout changes. Sorry for the poor JS code, I'm in an internet cafe.

Thanks,
Attila

@tabatkins
Copy link
Member

I'm sorry, I also can't tell what's being proposed from this example. Removing the --flex-wrap-layout property does almost nothing - as far as I can tell it just makes the "Item 1" line slightly narrower so it matches the width of the graph area?

Could you explain what behavior you're intending? I presume you intend for the #container's grandchildren (which are not, currently, flex items) to somehow interact in the flex layout algorithm, and tie their sizes together in some way across rows?

This example in particular seems very inappropriate for that, tho. The #container does not want to reflow, it wants to have exactly two items on the first row and two items on the second row (with one of the second row's items just being a spacer, to force the horizontal labels into the correct position). This, at a fundamental level, is not a flexbox, it's a grid; it has a meaningful two-dimensional layout structure, not a linear one. What benefit do you think you'd get from writing this layout as a flexbox?

(Rereading, I think it's just that you're using a JS library that understands flexbox but not grid, right? If so, then yeah, that's a reason to fix the library, not to make flexbox act like grid.)

@artit91
Copy link
Author

artit91 commented Mar 11, 2023

With all respect, I think you are wrong. It's clearly visible from the HTML that it's one dimensional. All areas are declared in the same level in order.

I will give you an example from many:

image

Source code is a bunch of words, one dimension but vs code is able to figure out how to align on line break from the context.

I believe we should have an option to align line breaks. Although I admit that my proposal was quite specific and hard to understand.

@tabatkins
Copy link
Member

I don't understand what your source code example is trying to say. It looks like you're trying to draw a metaphor to source-code indentation?

It's clearly visible from the HTML that it's one dimensional. All areas are declared in the same level in order.

Here's your HTML again, to be clear:

<div class="container">
  <div class="yAxis">
    <span>100%</span>
    <span>75%</span>
    <span>25%</span>
    <span>0%</span>
  </div>
  <div class="graph">
    <span height40></span>
    <span height20></span>
    <span height100></span>
    <span height10></span>
  </div>
  <div class="spacer"></div>
  <div class="xAxis">
    <span>Item 1</span>
    <span>Item 2</span>
    <span>Item 3</span>
    <span>Item 4</span>
  </div>
</div>

The container has three children, each of which have four spans. Without context, I could imagine someone wanting each child to be a row or column, with the spans aligned across them, but that's Grid Layout, and already doable (set the container to display:grid, make the children subgrids, then the spans will be grid items and will line up).

But that's not what you're doing. Instead, the second child is a bar graph, while the first and third are axis labels for that graph. These are fundamentally not 1-dimensional layout; the three children interact in a very specific 2-d fashion. If you tried to lay out all three children in one row, it would produce a nonsensical, unreadable result. Instead, you must have the first be laid out vertically and positioned horizontally adjacent to the graph, while the third is laid out horizontally and must be positioned vertically adjacent to the graph.

So, I'm still not certain what benefit you think you're getting from trying to use a Flexbox here (besides just "the JS library I'm using understands Flex but not Grid").

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

5 participants