Brad
Brad

Reputation: 479

Disply flex order CSS

I have a grid that will display many divs with content. At the moment, it is in 2 rows, splitting the divs 50% height.

This is correct, however it is in the following order:-

1,3,5, 7,9,11
2,4,6, 8,10,12

However I would like it to show the following way:-

1,2,3, 7,8,9
4,5,6, 10,11,12

I would like to keep the horizontal scroll in place, so it only shows 2 divs per row.

Ideally, I do not want to add any extra divs if possible, I need to just change the order. I also want it to show the first 6 posts, so 1,2,3,4,5,6. I have made a codepen here:- https://codepen.io/scottYg55/pen/bGdXEVw

.tiles {
  height: 1000px;
  overflow-x: scroll !important;
}

.tiles {
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -ms-flex-direction: column;
  -webkit-flex-direction: column;
  flex-direction: column;
  flex-wrap: wrap;
  height: 100vh;
  overflow: auto;
  position: relative;
  /* transform: rotateX(180deg); */
}

.tiles .tile:nth-child(1n) {
  flex-basis: calc(50%);
  background: red !important;
}

.tiles .tile {
  flex-basis: calc(100% / 2);
  width: calc(100% / 3);
  position: relative;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  color: white;
  overflow: hidden;
  box-sizing: border-box;
  /* transform: rotateX(180deg); */
}
<div class="tiles">
  <div class="tile">1</div>
  <div class="tile">2</div>
  <div class="tile">3</div>
  <div class="tile">4</div>
  <div class="tile">5</div>
  <div class="tile">6</div>
  <div class="tile">7</div>
  <div class="tile">8</div>
  <div class="tile">9</div>
  <div class="tile">10</div>
  <div class="tile">11</div>
  <div class="tile">12</div>
</div>

Does anyone know the best way to do this?

Thank you!

Upvotes: 1

Views: 126

Answers (2)

Temani Afif
Temani Afif

Reputation: 272598

You can do this using CSS grid easily:

.tiles {
  display: grid;
  grid-auto-flow: column dense;
  grid-auto-columns:calc((100% - 20px)/3);
  grid-auto-rows: 80px;
  grid-gap:10px;
  overflow: auto;
  counter-reset:num 0;
}

.tiles .tile {
  background: red;
  font-size:50px;
  color:#fff;
  grid-row:1;
}

.tiles .tile:nth-child(6n + 4),
.tiles .tile:nth-child(6n + 5),
.tiles .tile:nth-child(6n + 6){
  grid-row:2;
  background:blue;
}

.tiles .tile:before {
  content:counter(num);
  counter-increment:num;
}
<div class="tiles">
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
  <div class="tile"></div>
</div>

Upvotes: 2

disinfor
disinfor

Reputation: 11533

You need to use the order property for each element.

There might be a better way to set up the order number, but manually it looks like this:

.tiles {
  height: 1000px;
  overflow-x: scroll !important;
}

.tiles {
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -ms-flex-direction: column;
  -webkit-flex-direction: column;
  flex-direction: column;
  flex-wrap: wrap;
  height: 100vh;
  overflow: auto;
  position: relative;
  /* transform: rotateX(180deg); */
}

.tiles .tile:nth-child(1n) {
  flex-basis: calc(50%);
  background: red !important;
}

.tiles .tile:nth-child(1) {
  order: 1;
}

.tiles .tile:nth-child(2) {
  order: 3;
}

.tiles .tile:nth-child(3) {
  order: 5;
}

.tiles .tile:nth-child(4) {
  order: 2;
}

.tiles .tile:nth-child(5) {
  order: 4;
}

.tiles .tile:nth-child(6) {
  order: 6;
}

.tiles .tile:nth-child(7) {
  order: 7;
}

.tiles .tile:nth-child(8) {
  order: 9;
}

.tiles .tile:nth-child(9) {
  order: 9;
}


.tiles .tile:nth-child(10) {
  order: 10;
}

.tiles .tile:nth-child(11) {
  order: 11;
}

.tiles .tile:nth-child(12) {
  order: 12;
}

.tiles .tile {
  flex-basis: calc(100% / 2);
  width: calc(100% / 3);
  position: relative;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  color: white;
  overflow: hidden;
  box-sizing: border-box;
  /* transform: rotateX(180deg); */
}
<div class="tiles">
  <div class="tile">1</div>
  <div class="tile">2</div>
  <div class="tile">3</div>
  <div class="tile">4</div>
  <div class="tile">5</div>
  <div class="tile">6</div>
  <div class="tile">7</div>
  <div class="tile">8</div>
  <div class="tile">9</div>
  <div class="tile">10</div>
  <div class="tile">11</div>
  <div class="tile">12</div>
</div>

Edit: Since you're using WordPress, you can use the modulo operator to count the posts and wrap every six posts: https://www.php.net/manual/en/language.operators.arithmetic.php

SAMPLE QUERY (since I don't know what yours looks like):

if ( have_posts ) :
    // This is how many posts your query found
    $post_count = $wp_query->found_posts;
    // Setup an iterator to count posts;
    $i = 0;
    // start the loop.  
    while ( have_posts ) : the_post; 

        // This is where we check the posts to wrap.
        // Basically, if the iterator returns the remainder of 0 using 6 as the divider
        if ( $i%6 === 0 ) :
            echo '<div class="post-wrapper">';
        endif;

        /* ALL OF YOUR POST OUTPUT CODE GOES HERE */

        // Check the iterator again to add the closing wrapping div tag.
        // If the remainder is 5, that means it will be the last item in the loop or
        // if the total count minus 1, that means we are at the end of all posts.
        if ( $i%6 === 5 || $i === ( $post_count - 1 ) ) :
            echo '</div><!-- /post-wrapper -->';
        endif;

        // increment the iterator up one every time we loop.
        $i++;
    endwhile;
endif;

I didn't test with the actual WP loop, but did test on an array and got the output as expected. With the wrapped content, you can then change your CSS to keep the horizontal scroll, but you can use the blocks of posts as a flex element.

Upvotes: 0

Related Questions