3

Suppose I have this:

.flex-container {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}

.flex-container > div {
  background-color: DodgerBlue;
  color: white;
  width: 100px;
  margin: 10px;
  text-align: center;
  line-height: 75px;
  font-size: 30px;
}
<div class="flex-container">
  <div><a href="#">1</a></div>
  <div><a href="#">2</a></div>
  <div><a href="#">3</a></div>
</div>

How can I use flexbox to order the items, so the layout would be like this?

enter image description here

I cannot change the order of the divs in the HTML, since it would jeopardize the layout of a different view.

kukkuz
  • 41,512
  • 6
  • 59
  • 95
katus
  • 649
  • 1
  • 6
  • 16
  • Is there any way to achieve this layout without changing the HTML, since it would jeopardize the layout of a different view that I have? – katus Apr 10 '19 at 04:58
  • Does this answer your question? [Change div order with CSS depending on device-width](https://stackoverflow.com/questions/32829567/change-div-order-with-css-depending-on-device-width) – vsync Oct 22 '20 at 06:48

3 Answers3

6

Its easy if you can switch to CSS Grid layout:

  • create an grid container on flex-cotainer element

  • place the second element to first column (using grid-column: 1) spanning 2 rows (using grid-row: 1 / 3).

See demo below:

.flex-container {
  display: inline-grid;
  grid-template-columns: auto auto;
}

.flex-container div:nth-child(2) {
  grid-column: 1;
  grid-row: 1 / 3;
}

.flex-container > div {
  background-color: DodgerBlue;
  color: white;
  width: 100px;
  margin: 10px;
  text-align: center;
  line-height: 75px;
  font-size: 30px;
}
<div class="flex-container">
  <div><a href="#">1</a></div>
  <div><a href="#">2</a></div>
  <div><a href="#">3</a></div>
</div>

A flexbox solution is hacky at best using negative margins and known heights - see below:

.flex-container {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
}

.flex-container div:nth-child(1) {
  align-self: flex-start;
}

.flex-container div:nth-child(2) {
  order: -1;
  line-height: 170px;
}

.flex-container div:nth-child(3) {
  margin-left: auto;
  margin-top: -85px;
}

.flex-container > div {
  background-color: DodgerBlue;
  color: white;
  width: calc(100px - 20px);
  margin: 10px;
  text-align: center;
  line-height: 75px;
  font-size: 30px;
}
<div class="flex-container">
  <div><a href="#">1</a></div>
  <div><a href="#">2</a></div>
  <div><a href="#">3</a></div>
</div>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
  • Using Grid is a good idea, but it doesn't answer the question. It can be done very easily using Flexbox. – Nilpo Apr 10 '19 at 05:11
  • I don't disagree with you. But the question is can you change the order of flex items. And you can. You should indicate that it is possible and show how. Then show the better solution with grid. – Nilpo Apr 10 '19 at 05:21
1

You shouldn't use Flexbox for this because it's not designed for it. Consider using CSS Grid instead. Using grid-template-areas, assigning the children where we want them in the layout becomes a trivial task. The DOM order of the grid children becomes irrelevant.

.grid-container {
  display: inline-grid;
  grid-template-areas: "two one"
                       "two three";
}

.grid-container > div {
  background-color: DodgerBlue;
  color: white;
  width: 100px;
  margin: 10px;
  text-align: center;
  line-height: 75px;
  font-size: 30px;
}

.one {
  grid-area: one;
}

.two {
  grid-area: two;
}

.three {
  grid-area: three;
}
<div class="grid-container">
  <div class="one"><a href="#">1</a></div>
  <div class="two"><a href="#">2</a></div>
  <div class="three"><a href="#">3</a></div>
</div>
Andy Hoffman
  • 18,436
  • 4
  • 42
  • 61
1

Reverse the row order by using row-reverse instead of row for the flex-direction.

flex-direction: row-reverse;

You can also order the children manually by giving them each an order property that takes an integer.

.flex-container :nth-child(1) { order: 3; }
.flex-container :nth-child(2) { order: 2; }
.flex-container :nth-child(3) { order: 1; }
Nilpo
  • 4,675
  • 1
  • 25
  • 39
  • How does this answer the question? In addition, your `CSS` is not even valid. Even if it was, it would not properly answer the question. The second child is supposed to span two rows. – Andy Hoffman Apr 10 '19 at 05:16
  • This solution would have the divs as 3 rows parallel with one another in a flex container. I need to have and (1) stacked on (3) as though. Is there a way to do it with flexbox? – katus Apr 10 '19 at 05:16
  • @AndyHoffman The question doesn't have enough markup to use Flexbox. It's clearly stripped down for the question's sake. It doesn't ask for a working solution, it only asks how to change the order of the elements. – Nilpo Apr 11 '19 at 07:30
  • @Nilpo pretty sure it was Andy Hoffman, whose answer actually deserves the downvotes. I'll upvote your answer. – Neurotransmitter Feb 11 '20 at 12:47