6

I have 5 divs, every second div should have a different colour than the others.

<div class="element element1">Element1</div>
<div class="element element2">Element2</div>
<div class="element element3">Element3</div>
<div class="element element4">Element4</div>
<div class="element element5">Element5</div>

In my CSS I have

.element {
 background-color: grey;
}

.element:nth-child(odd) {
 background-color: pink;
}

Now dynamically the order of those elements will change, which I want to do with flexbox. Meaning my CSS looks like this then:

.element {
 background-color: grey;
 display:flex;
}

.element5 {
 order: 1;
}

.element2 {
 order: 2;
}

As flexbox is not changing the DOM, the nth-child(odd) will still style every second DOM Element, which is not the order the user will see. But that's what I want. Every second element the users sees should have a different colour, even if the element changes the order with flexbox. Has anyone an idea how this could work? I can only use CSS or HTML for this, no JavaScript or PHP.

Barbara
  • 61
  • 1
  • 1
  • 3
  • 1
    Possible duplicate of [Zebra striping a flexbox table with wrapping items](http://stackoverflow.com/questions/35355253/zebra-striping-a-flexbox-table-with-wrapping-items) – TylerH Aug 03 '16 at 15:52
  • I guess that's different. Unfortunately I don't have a class where I can add the background-colour too, this has to be done dynamically by CSS/SASS – Barbara Aug 03 '16 at 15:58
  • You can't do this with CSS...you'd need javascript.,,and even then it'd be tricky. – Paulie_D Aug 03 '16 at 16:02
  • Thanks Paulie, I already thought so too. Mhm.. damn! – Barbara Aug 03 '16 at 16:05
  • @Barbara I figured it couldn't be done with CSS initially (you may have even seen my comment before I deleted it), but that potential dupe gave me a little hope. Just a word to the wise: Sass can't do anything CSS can't do (since it compiles into CSS before it hits the browser); it only exists to make writing CSS a quicker task. – TylerH Aug 03 '16 at 17:35
  • The `order` property only affects the screen display. The `nth-child` pseudo-class always looks at the DOM. Hence, combining `order` and `nth-child` will not work. Maybe one day we'll have `nth-order` :-) For now, consider JS. – Michael Benjamin Aug 03 '16 at 19:00
  • @Barbara how do you do the change of the order in SASS? maybe is possible define the background in the same function –  Aug 04 '16 at 06:36
  • 3
    @Michael_B nth-order would be perfect for this! I will write w3c to add this to CSS :-) – Barbara Aug 04 '16 at 09:53

2 Answers2

2

Assuming the layout is always going to be as you put it above.

First You need to set display flex in a container, not in the elements.

Second, if you set Element 5|2 to order 1|2 respectively they will always be at the end as default order is 0(zero).

so you end with | assume bold is odd new colour

ORIGINAL ORDER(DOM): 1 2 3 4 5

FLEX ORDER: 1 3 4 5 2

.flex-container {
  /*SET DISPLAY FLEX ON CONTAINER*/ 
  -ms-box-orient: horizontal;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -moz-flex;
  display: -webkit-flex;
  display: flex;
  
  -webkit-flex-flow: row wrap;
  flex-flow: row wrap;
}
/*SET THE NEW ORDER*/
.element:nth-of-type(2){ order: 2;}
.element:nth-of-type(5) { order: 1; }

/*PRESENTATION PROPOUSES ONLY*/
.element,
.normal{
  background: grey;
  padding: 5px;
  width: 100px;
  height: 100px;
  margin: 5px;
  
  line-height: 100px;
  color: white;
  font-weight: bold;
  font-size: 2em;
  text-align: center;
}

/* TARGET NEW ODD ELEMENTS*/
.element:nth-of-type(1),
.element:nth-of-type(2),
.element:nth-of-type(4){
  background: pink;
}

/* TARGET ORIGINAL ORDER*/
.normal:nth-child(odd){
background: pink;
}
<h1>FLEX ORDER</h1>
<div class="flex-container">
  <div class="element element1">1</div>
  <div class="element element2">2</div>
  <div class="element element3">3</div>
  <div class="element element4">4</div>
  <div class="element element5">5</div>
</div>
<h1>ORIGINAL ORDER</h1>
<div class="flex-container">
  <div class="normal">1</div>
  <div class="normal">2</div>
  <div class="normal">3</div>
  <div class="normal">4</div>
  <div class="normal">5</div>
</div>

If you were to use the Flex & Order only in certain device.Let's say you want default order(12345) in mobile and flex + order(13452) from tablet up you can have @media queries leaving the default(ORIGINAL ORDER) to change colours with nth-child(odd) and then for other devices inside media queries add the above code(FLEX ORDER).

Thanks.

T04435
  • 12,507
  • 5
  • 54
  • 54
-1

My solution:

div {
  display: flex;
  flex-direction: column;
}

div > div {
  order: 1;
  background-color: #868d95;
}

div > div:nth-child(odd) {
  background-color: #a7acb2;
}

div > div.active {
  order: 0;
  background-color: #20c36d;
}

div > div.active ~ div {
  background-color: #a7acb2;
}

div > div.active ~ div:nth-child(odd) {
  background-color: #868d95;
}
<div>
  <div>1</div>
  <div>2</div>
  <div class="active">3</div>
  <div>4</div>
  <div>5</div>
  <div>7</div>
  <div>8</div>
</div>

scss:

div {
  display: flex;
  flex-direction: column;

  & > div {
    order: 1;
    background-color: #868d95;

    &:nth-child(odd) {
      background-color: #a7acb2;
    }

    &.active {
      order: 0;
      background-color: #20c36d;

      & ~ div {
        background-color: #a7acb2;

        &:nth-child(odd) {
          background-color: #868d95;
        }
      }
    }
  }
}
dFelinger
  • 97
  • 1
  • 8