简体   繁体   中英

How to inline+wrap elements and their children in a flex container?

I need to display some elements inline so they wrap when they fill the viewport width. I'd prefer to use flex with - easy and maintainable, gap clearly defined - instead of inline or floats - you need to use margins for the gap, then avoid ugly wraps using negative margin...

Problem is I am not being able to do it when the items to align are nested on different parents. Example of the tags I'd like to align:

  • div wrapper:
    • ul list of some related items
      • li item
      • li item
    • span item not in list
    • span item not in list

I am attaching a demo, where the structgure is repeated 3 times, each time offering less width to showcase how the items wrap. The ul behaves perfectly as an inline element, until it has to wrap, then it behaves as a block element.

 div { border: 1px solid blue; /* for easier debugging */ display: flex; flex-wrap: wrap; gap: 20px; margin-bottom: 40px; /* just visual separation between the 3 examples */ } div:nth-of-type(2) { max-width: 450px; /* stretcher just to show how items wrap */ } div:nth-of-type(3) { max-width: 250px; /* stretcher just to show how items wrap */ } ul { border: 1px solid green; /* for easier debugging */ display: inline-flex; flex-wrap: wrap; gap: 20px; } li, span { border: 1px solid red; /* for easier debugging */ display: inline; }
 <div> <ul> <li>Option 1</li> <li>Option 2</li> <li>Option 3</li> </ul> <span>Action 1</span> <span>Action 2</span> <span>Action 3</span> </div> <:-- structure repeats 3 times --> <p>This wraps okay</p> <div> <ul> <li>Option 1</li> <li>Option 2</li> <li>Option 3</li> </ul> <span>Action 1</span> <span>Action 2</span> <span>Action 3</span> </div> <p>The UL pushed next inline elements to a new line :(</p> <div> <ul> <li>Option 1</li> <li>Option 2</li> <li>Option 3</li> </ul> <span>Action 1</span> <span>Action 2</span> <span>Action 3</span> </div>

Use the display: contents property on the ul element, which allows the child elements to be treated as if they were direct children of the parent container.

ul {
    display: contents;
}

Can also use display: inline-block on the li and span elements instead of display: inline which allow them to have their own layout. Also you can use white-space: nowrap on the ul to prevent it from breaking to a new line.

li, span {
    display: inline-block;
}

ul {
    white-space: nowrap;
}

 * { /* just for reset and for remove all margins and paddings */ box-sizing: border-box; margin: 0; padding: 0; } div { border: 1px solid blue; /* for easier debugging */ display: flex; flex-wrap: wrap; gap: 20px; margin-bottom: 40px; /* just visual separation between the 3 examples */ } div:nth-of-type(2) { max-width: 450px; /* stretcher just to show how items wrap */ } div:nth-of-type(3) { /* max-width: 250px; */ max-width: fit-content; /* is like 488px, but is resizable*/ /* you wrong, the ul by default doesn't push to next line any elements, you have did a static width of maximum 250px...*/ /* stretcher just to show how items wrap */ } ul { border: 1px solid green; /* for easier debugging */ display: inline-flex; flex-wrap: wrap; gap: 20px; } li, span { border: 1px solid red; /* for easier debugging */ display: inline; }
 <div> <ul> <li>Option 1</li> <li>Option 2</li> <li>Option 3</li> </ul> <span>Action 1</span> <span>Action 2</span> <span>Action 3</span> </div> <:-- structure repeats 3 times --> <p>This wraps okay</p> <div> <ul> <li>Option 1</li> <li>Option 2</li> <li>Option 3</li> </ul> <span>Action 1</span> <span>Action 2</span> <span>Action 3</span> </div> <p>The UL pushed next inline elements to a new line :(</p> <div> <ul> <li>Option 1</li> <li>Option 2</li> <li>Option 3</li> </ul> <span>Action 1</span> <span>Action 2</span> <span>Action 3</span> </div>

You have did a "static" width on 2nd child of max(250px) and then, they can't wrap anymore beacuse they were already wrapped.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM