PetaspeedBeaver
PetaspeedBeaver

Reputation: 433

Make one flex item occupy the entire column

I have an unordered list in a flex layout. I want the first li item (which is the "home" link of a menu) to be positioned in its own column like this:

enter image description here

How can I do that?


Due to semantics I don't want to break out the first list item and put it in a separate div. I want it to be in the list in the HTML.

* {
  outline: solid 1px grey;
}
ul {
  display: flex;
  flex-wrap: wrap;
  list-style-type: none;
  white-space: nowrap;
}

li {
  flex: 1;
}

ul > li:first-child {
  /* This item should be in its own column */
  color: green;
}
<ul>
  <li>
    First item and this is it
  </li>
  <li>
    Second item this is the sh*t
  </li>
  <li>
    Third after two to go
  </li>
  <li>
    Forth enabled flex is flow
  </li>
  <li>
    Fifth the rabbit digs a hole
  </li>
  <li>
    Sixth hole in the pork says "miew"
  </li>
</ul>

http://codepen.io/rooeee/pen/ObZwER

Upvotes: 4

Views: 2248

Answers (1)

Michael Benjamin
Michael Benjamin

Reputation: 371113

In a flex container with row wrap there's really no way to achieve this layout, unless you add containers. I understand you prefer not to change the HTML.

However, if you can switch to column wrap and define a height for the container, then you can make the first link occupy the whole column by giving it flex-basis: 100%. This forces subsequent items to wrap.

revised codepen

ul {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  list-style-type: none;
  white-space: nowrap;
  height: 100px;
}
li {
  flex: 0 0 50%;
}
ul > li:first-child {
  flex-basis: 100%;
  color: green;
}
* {
  outline: solid 1px grey;
  box-sizing: border-box;
}
<ul>
  <li>
    First item and this is it
  </li>
  <li>
    Second item this is the sh*t
  </li>
  <li>
    Third after two to go
  </li>
  <li>
    Forth enabled flex is flow
  </li>
  <li>
    Fifth the rabbit digs a hole
  </li>
  <li>
    Sixth hole in the pork says "miew"
  </li>
</ul>


ALSO, if your only reason for not wanting to alter the HTML is semantics, you can still build the layout in a row-based container while adhering to clean, valid and semantic code. In other words, creating nested flex containers is fine.

revised codepen

ul {
  display: flex;
  list-style-type: none;
	white-space: nowrap;
}
ul:first-child > li:first-child {
  flex: 0 0 20%;
}
ul:first-child > li:nth-child(2) {
  flex: 0 0 80%;
}
ul:first-child > li:nth-child(2) ul {
  flex-wrap: wrap;
}
ul:first-child > li:nth-child(2) li {
  flex: 0 0 50%;
}
* {
  box-sizing: border-box;
  padding: 0;
  outline: solid 1px grey;
}
<ul><!-- primary flex container -->
  <li>First item and this is it</li><!-- flex item #1 -->
  <li><!-- flex item #2 -->
    <ul><!-- nested flex container -->
      <li>Second item this is the sh*t</li><!-- flex item -->
      <li>Third after two to go</li><!-- flex item -->
      <li>Forth enabled flex is flow</li><!-- flex item -->
      <li>Fifth the rabbit digs a hole</li><!-- flex item -->
      <li>Sixth hole in the pork says "miew</li><!-- flex item -->
    </ul><!-- END nested flex container -->
  </li><!-- END flex item #2 -->
</ul><!-- END primary flex container -->

Upvotes: 3

Related Questions