Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the CSS flexbox module work on direct child elements only?

Tags:

Have a look at this page design of a site I own and run:

http://www.jungledragon.com/image/9472/barn_owl_close-up.html

As you can see, this concerns a classic two-column layout. The order of things is important. For example, you can see directly next to the photo what specie this concerns.

I'm now coding a responsive design for this site, and facing a challenge. Imagine that page on a narrow smartphone viewport. The classic strategy would be to simply "stack" the right column below the left one and let users scroll vertically. However, this is far from ideal in terms of the ordering of elements. The 'specie' block would be way below the photo, users would first have to scroll through things like comments before they can see the relationship between the photo and the specie.

I'm trying to solve that, and this article which explains CSS's flexbox as a possible solution sounded very promising:

http://www.jordanm.co.uk/post/21863299677/building-with-content-choreography

The idea here is that using CSS only, one can change the visual order of elements, exactly what I need. Unfortunately, since then I learned that the article uses the outdated spec, and that the new spec is barely supported by any browser:

http://css-tricks.com/old-flexbox-and-new-flexbox/

This kind of ruins it for me. Nevertheless, I'd still like to ask my question at the conceptual level:

All of the demos that I have seen regarding flexbox have markup as simple as this:

<div id="somecontainer">
  <div id="child1"></div>
  <div id="child2"></div>
</div>

Next, the container is declared to be a flexbox, direction vertical. And finally, an order is assigned to each child element. This allows for example child2 to be moved above child1, using a single CSS statement.

Now here's the question. What if the actual markup is more complex in the sense that there are additional hierarchies at play? An example:

<div id="somecontainer">

  <div id="colmain">

    <div id="content1"></div>
    <div id="content2"></div>
    <div id="content3"></div>

  </div>

  <div id="colside">

    <div id="content4"></div>
    <div id="content5"></div>
    <div id="content6"></div>

  </div>

</div>

As you can see, this markup has additional hierarchies, the actual content blocks to be reordered are not direct child elements of the highest level container. They are childs but not direct childs.

Could flexbox and the reordering of child elements work in such a scenario? Could for example "content5" be moved in between "content1" and "content2"?

Regardless of poor browser support, I'm trying to conceptually understand whether that would be supported. The reason I ask is because the additional column hierarchies are extremely common in markup and it would totally suck if flexbox reordering would work only on direct childs.

like image 742
Fer Avatar asked Jan 03 '13 22:01

Fer


People also ask

Does display flex only apply to direct children?

Flex layout only applies to the direct children of a flex container. By adding display: contents to the wrapper around the nested elements, you can see that the item has disappeared from the layout, allowing the two sub-children to be laid out as if they were direct children of the flex container.

Can I use flexbox for everything?

You could use flexbox on everything but you really shouldn't. Flexbox is a new layout algorithm for laying out complex web pages/applications, but he also have it disadventages(temporarily the most slower layout). Basically flexbox is the most best for smaller page components and UI elements.

Does display flex affect all children?

The flexbox code is triggered on the parent element, but affects all of the child elements.

What element do you target flexbox on to parent or child?

You'd call the ul the parent element, and the li the child element. To use the Flexbox model, you must make a parent element a flex container (AKA flexible container). You do this by setting display: flex or display: inline-flex for the inline variation.


3 Answers

To answer your question title: yes, this is actually stated quite clearly in the spec:

The contents of a flex container consists of zero or more flex items: each child of a flex container becomes a flex item

In case the wording in the spec confuses you, that's because your wording is a bit off:

They are childs but not direct childs.

A child is direct by definition... the inner divs are called descendants, but not children in that they're not directly nested within the flex container.

Now, anything with display: flex or display: inline-flex is designated a flex container. While each flex item participates in the flex container's formatting context, the flex item's descendants are formatted independently and regardless of the flex container, being the same as if the container was never flexed in the first place.

As such, you can't reorder descendants of flex items, except if the flex item itself is also made a flex container for its descendants, but even then you cannot reorder them beyond this inner container and around the container's siblings with respect to the outer container.

like image 154
BoltClock Avatar answered Oct 17 '22 05:10

BoltClock


BoltClock's answer is great but I want to add an important note:

It's the (direct) children boxes of the flex container which become flex items. But those don't necessarily correspond to (direct) children elements.

Some examples:

  • The ::before and ::after pseudo-elements of the flex container generate flex items.
  • Each contiguous run of text that is directly contained inside a flex container is wrapped in an anonymous flex item.
  • If a child element of a flex container has display: contents, it won't be rendered, and its children (grandchildren of the flex container) will be displayed as flex items.

Then, if you have a complex structure inside the flex container, and you want the leaves of the tree to be flex items of the outer container, you can style all intermediate elements with display: contents.

However, note display: contents is a recent addition, so it's not widely supported yet.

like image 29
Oriol Avatar answered Oct 17 '22 05:10

Oriol


Some potential solutions will be the CSS Grid layout: http://dev.w3.org/csswg/css3-grid-layout/ however at the time of writing only IE10 supports it: http://caniuse.com/css-grid

and template layout http://www.w3.org/TR/2009/WD-css3-layout-20090402/

Not sure if either are being developed though, or if we'll have another flex-box type thing with lots of similar but changing syntaxes

like image 30
Ric Avatar answered Oct 17 '22 06:10

Ric