ditto ditto - 2 months ago 13
CSS Question

Making an S shape with flexbox

I'm trying to reproduce this layout structure using flex.

ooo
o
ooo
o
ooo
o
ooo


I can achieve this with regular display block/inline-block but I'm wrapping some elements just for positioning, and it feels hackish.



span {
display:inline-block;
width: 100px;
height:100px;
background:black;
color:white;
font-size:11px;
}

.new {
display:block;
}

.right {
margin-left:200px;
}

* {
font-size:0;
margin:0;
padding:0;
}

.alignright {
direction: rtl;
}

section {
width:300px;
}

<section>

<span class="row">1</span>
<span class="row">2</span>
<span class="row">3</span>

<span class="new right">4</span>
<span class="new right">5</span>

<div class="alignright">
<span class="row t">6</span>
<span class="row t">7</span>
<span class="row t">8</span>
</div>

<span class="new">9</span>
<span class="new">10</span>

<span class="row">11</span>
<span class="row">12</span>
<span class="row">13</span>

</section>





Is this possible to do in flex, without the
DIV
wrappings and multiple classes?

Answer

This can be achieved using flexbox and nth-child

You can use nth-child to mark which elements are to align to the left and right and flexboxes order property means you do not need any nesting.

The following changes are required:

  • Add display: flex; and flex-wrap: wrap; to section to make it's children use the flexbox model and wrap onto new lines
  • Add span:nth-child(-n+5) with order: 1; - this will tell the first 5 elements to be ordered first
  • Add span:nth-child(4), span:nth-child(5) with margin-right: 200px; - this will force the fourth and fifth elements to take up the extra space on the right and push subsequent elements onto a new line
  • Add span:nth-child(8) with order: 2; - this will order the eighth element after the first five
  • Add span:nth-child(7) with order: 3; - this will order the seventh element after the eighth
  • Add span:nth-child(6) with order: 4; - this will order the sixth element after the seventh
  • Add span:nth-child(n+9) with order: 5; - this will order the last 5 elements after the sixth
  • Add span:nth-child(9), span:nth-child(10) with margin-left: 200px; - this will force the ninth and tenth elements to take up the extra space on the left and push subsequent elements onto a new line

* {
  font-size: 0;
  margin: 0;
  padding: 0;
}
section {
  display: flex;
  flex-wrap: wrap;
  width: 300px;
}
span {
  background: black;
  color: white;
  font-size: 11px;
  height: 100px;
  width: 100px;
}
span:nth-child(-n+5) {
  order: 1;
}
span:nth-child(4),
span:nth-child(5) {
  margin-left: 200px;
}
span:nth-child(6) {
  order: 4;
}
span:nth-child(7) {
  order: 3;
}
span:nth-child(8) {
  order: 2;
}
span:nth-child(n+9) {
  order: 5;
}
span:nth-child(9),
span:nth-child(10) {
  margin-right: 200px;
}
<section>
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
  <span>6</span>
  <span>7</span>
  <span>8</span>
  <span>9</span>
  <span>10</span>
  <span>11</span>
  <span>12</span>
  <span>13</span>
</section>

Comments