Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make CSS Flex Elements Ignore Container Element

Tags:

html

css

flexbox

I'm working to create a component similar to Chosen, but I'm running into an issue with flex and wrapping. The gist is that each "chip" in the pseudo textbox needs to be in a container that does not also contain the actual text input, but I need those chips to be treated as a flex element on the same basis as the input.

My HTML structure looks like this:

<div class="box">
  <div class="chipContainer">
    <div class="chip">Chip1</div>
    <div class="chip">Chip2</div>
    <div class="chip">Chip3</div>
    <div class="chip">Chip4</div>
  </div>
  <input class="textbox" type="text">
</div>

This Plunker example is more complete and has styles roughly equivalent to what I'm working with currently.

.box {
  background: #fff;
  border: 1px solid #ccc;
  width: 500px;
  overflow: auto;
  padding: 2px;
  display: flex;
  flex-wrap: wrap;
}
.chip {
  display: inline-block;
  border: 1px solid #ccc;
  background: #eee;
  padding: 2px;
  margin-right: 1px;
  flex: auto;
}
.textbox {
  border: none;
  background: #fdd;
  font-size: 18px;
  flex: auto;
}
.textbox:focus {
  outline: none;
}
.chipContainer {
  display: inline;
}
<div class="box">
  <div class="chipContainer">
    <div class="chip">Chip1</div>
    <div class="chip">Chip2</div>
    <div class="chip">Chip3</div>
    <div class="chip">Chip4</div>
  </div>
  <input class="textbox" type="text">
</div>
<br>
<div class="box">
  <div class="chipContainer">
    <div class="chip">Chip1</div>
    <div class="chip">Chip2</div>
    <div class="chip">Chip3</div>
    <div class="chip">Chip4</div>
    <div class="chip">Chip5</div>
    <div class="chip">Chip6</div>
    <div class="chip">Chip7</div>
    <div class="chip">Chip8</div>
    <div class="chip">Chip9</div>
    <div class="chip">Chip10</div>
    <div class="chip">Chip11</div>
  </div>
  <input class="textbox" type="text">
</div>

As you can see, after enough chips have been added to the .box container the .chipContainer will begin to wrap them, but .chipContainer remains a block element and pushes the input down to a new line entirely.

This Plunker example demonstrates my goal. The layout can be achieved fairly easily once .chipContainer is removed, however it's a fairly essential element in the component's structure, and I would prefer to solve this without removing it, if possible.

.box {
  background: #fff;
  border: 1px solid #ccc;
  width: 500px;
  overflow: auto;
  padding: 2px;
  display: flex;
  flex-wrap: wrap;
}
.chip {
  display: inline-block;
  border: 1px solid #ccc;
  background: #eee;
  padding: 2px;
  margin-right: 1px;
  flex: auto;
  min-width: 50px;
  max-width: 60px;
}
.textbox {
  border: none;
  background: #fdd;
  font-size: 18px;
  flex: auto;
  min-width: 250px;
}
.textbox:focus {
  outline: none;
}
.chipContainer {
  display: inline;
}
<div class="box">
  <div class="chip">Chip1</div>
  <div class="chip">Chip2</div>
  <div class="chip">Chip3</div>
  <div class="chip">Chip4</div>
  <input class="textbox" type="text">
</div>
<br>
<div class="box">
  <div class="chip">Chip1</div>
  <div class="chip">Chip2</div>
  <div class="chip">Chip3</div>
  <div class="chip">Chip4</div>
  <div class="chip">Chip5</div>
  <div class="chip">Chip6</div>
  <div class="chip">Chip7</div>
  <div class="chip">Chip8</div>
  <div class="chip">Chip9</div>
  <input class="textbox" type="text">
</div>
like image 407
Zikes Avatar asked Jun 24 '15 17:06

Zikes


People also ask

How do I ignore an element in flexbox?

You can use flex-shrink: 0 on the child elements to keep them from shrinking to fill the container. And use flex-wrap: wrap on the container/wrapper so your children will wrap down. Save this answer.

How do I stop flexbox overflow?

To prevent horizontal overflow, you can: Use flex-basis: 0 and then let them grow with a positive flex-grow . Use a positive flex-shrink to let them shrink if there isn't enough space.

Does CSS columns have effect on a Flex container?

display. This defines a flex container; inline or block depending on the given value. It enables a flex context for all its direct children. Note that CSS columns have no effect on a flex container.

Why is my flexbox overflowing?

This means that if you have a set of flex items that are too wide for their container, they will overflow it. If you want to cause them to wrap once they become too wide you must add the flex-wrap property with a value of wrap , or use the shorthand flex-flow with values of row wrap or column wrap .


1 Answers

Display Module Level 3 instroduces display: contents:

The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.

So you just need

.chipContainer {
  display: contents;
}

.box {
  background: #fff;
  border: 1px solid #ccc;
  width: 500px;
  overflow: auto;
  padding: 2px;
  display: flex;
  flex-wrap: wrap;
}
.chip {
  display: inline-block;
  border: 1px solid #ccc;
  background: #eee;
  padding: 2px;
  margin-right: 1px;
  flex: auto;
  min-width: 50px;
  max-width: 60px;
}
.textbox {
  border: none;
  background: #fdd;
  font-size: 18px;
  flex: auto;
}
.textbox:focus {
  outline: none;
}
.chipContainer {
  display: contents;
}
<div class="box">
  <div class="chipContainer">
    <div class="chip">Chip1</div>
    <div class="chip">Chip2</div>
    <div class="chip">Chip3</div>
    <div class="chip">Chip4</div>
  </div>
  <input class="textbox" type="text">
</div>
<br>
<div class="box">
  <div class="chipContainer">
    <div class="chip">Chip1</div>
    <div class="chip">Chip2</div>
    <div class="chip">Chip3</div>
    <div class="chip">Chip4</div>
    <div class="chip">Chip5</div>
    <div class="chip">Chip6</div>
    <div class="chip">Chip7</div>
    <div class="chip">Chip8</div>
    <div class="chip">Chip9</div>
    <div class="chip">Chip10</div>
    <div class="chip">Chip11</div>
  </div>
  <input class="textbox" type="text">
</div>

However, note it's not widely supported yet.

like image 140
Oriol Avatar answered Sep 23 '22 18:09

Oriol