5

Is there a CSS-only way of ordering items in columns for grid layout without using pixel values? Flexbox would work as well. I need the same HTML to enable the following two scenarios (with numbers of columns between 1 and 5 in the dynamically-generated HTML):

Case A:

| item 1          | item 2          | item 3          |
| item 4          | item 5          | item 6          |
| item 7          | item 8          | item 9          |

Case B:

| item 1          | item 4          | item 7          |
| item 2          | item 5          | item 8          |
| item 3          | item 6          | item 9          |

Case A is easy, just need to do something like:

.case-a[data-column-count='3'] {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
}

<div data-column-count="3" class="case-b">
     <label>item 1</label>
     <label>item 2</label>
     <label>item 3</label>
</div>

The closest I came to it is this Codepen, though vertical alignment is messy on each individual column: https://codepen.io/anon/pen/zbGWRa

body {
  font-family: sans-serif;
}

.columns {
  column-width: 18vw;
}
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 2em;
  grid-gap: .5em;
  align-items: center;
  background: #eee;
  padding: .5em;
  box-decoration-break: clone;
  counter-reset: nb;
  border: 2px solid red;
}
input {
  align-self: stretch;
  border-radius: 2px;
  border: 1px solid #ccc;
}
label::before {
  counter-increment: nb;
  content: counter(nb) ". ";
}
<div class="columns">
  <div class="grid">
    <label>label</label>
    <input type="text">
    <label>label</label>
    <input type="text">
    <label>label</label>
    <input type="text">
    <label>label</label>
    <input type="text">
    <label>label</label>
    <input type="text">
    <label>label</label>
    <input type="text">
    <label>label</label>
    <input type="text">
  </div>
</div>

Another Codepen - I can also indirectly control the number of columns by specifying the number of items per column, but I want to just specify a number of columns: https://codepen.io/anon/pen/BbNqGE

.container {
  display: grid;
  grid-template-columns: 1fr;
}

.container {
  grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
  grid-auto-columns: 1fr;
  grid-auto-flow: column;
}

* {
  box-sizing: border-box;
}

body {
  font-size: 1.35em;
  font-family: 'Varela Round', sans-serif;
  color: #fff;
  background: #e8e9e9;
  padding-left: 5%;
  padding-right: 5%;
}

.container {
  padding: 10px;
  background: #fff;
  border-radius: 5px;
  margin: 45px auto;
}

.item {
  color: #fff;
  padding: 15px;
  margin: 5px;
  background: #3db5da;
}
<div class="container">
  <div class="item-1 item">Item 1</div>
  <div class="item-2 item">Item 2</div>
  <div class="item-3 item">Item 3</div>
  <div class="item-4 item">Item 4</div>
  <div class="item-5 item">Item 5</div>
  <div class="item-5 item">Item 6</div>
  <div class="item-5 item">Item 7</div>
</div>
montrealist
  • 5,593
  • 12
  • 46
  • 68
  • For some reason I am unable to load the codepen. It keeps freezing and flickering. – Nick Lee Feb 27 '19 at 18:59
  • That’s a chrome issue @NickLee – soulshined Feb 27 '19 at 19:14
  • 1
    Please do not use external code sites. Instead, use StackOverflow snippet functionality unless you need features those don't offer. – connexo Feb 27 '19 at 19:15
  • 1
    @connexo I would agree with you but I think it’s best to include both. SO mobile apps don’t support snippets (it looks like they don’t plan on it either) – soulshined Feb 27 '19 at 19:16
  • @soulshined Honestly the mobile app (at least on Android) sucks big time, I don't think it's relevant at all. I'd rather use SO on a browser on mobile. – connexo Feb 27 '19 at 19:21
  • @connexo mobile including iOS safari. I use it frequently (the app and safari) and both don’t support it. Either way snippets aren’t a universal solution (codepen has better library support for example, angular etc) just my 2 cents. Both would be appreciated whenever possible or necessary – soulshined Feb 27 '19 at 19:24
  • 1
    @soulshinedThat's why I added *unless you need features those don't offer*. This is not the case here. – connexo Feb 27 '19 at 19:41
  • @connexo inserted both snippets with code from Codepen. – montrealist Feb 27 '19 at 20:19

1 Answers1

3

You can do this with CSS' grid-template-area.

The code will look like this. Where grid-template-areas represents the placement. And in each id of the element will define the named area. grid-area: a;. The id selector of each element does not need to match the grid-are name as in my example.

*{
  box-sizing: border-box;
}
.wrapper {
  color:white;
  font-size: 2em;
  
  display:grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 100px 100px;
    
  grid-template-areas: 
                       "a d g"
                       "b e h"
                       "c f i";

}
#a{
  background-color:rgb(180,247,182);
  grid-area: a;
}
#b{
  background-color:rgb(250,235,122);
  grid-area:b;
}
#c{
  background-color:rgb(167,255,250);
  grid-area:c;

}
#d{
  background-color:rgb(227,176,252);
    grid-area:d;

}
#e{
  background-color:rgb(157,255,205);
  grid-area:e;

}
#f{
  background-color:rgb(243,152,98);
    grid-area:f;

}
#g{
  background-color:rgb(55,32,199);
    grid-area:g;

}
#h{
  background-color:rgb(120,152,98);
    grid-area:h;

}
#i{
  background-color:rgb(243,100,98);
    grid-area:i;

}

.wrapper > div {
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="wrapper">
  <div id="a">1</div>
  <div id="b">2</div>
  <div id="c">3</div>
  <div id="d">4</div>
  <div id="e">5</div>
  <div id="f">6</div>
  <div id="g">7</div>
  <div id="h">8</div>
  <div id="i">9</div>

</div>
Nick Lee
  • 842
  • 2
  • 11
  • 27
  • 2
    That's nice. Though it means that I need to know the number of items in advance (to at least be able to generate names for the grid areas (which I don't have - items will be editable by users of the component I'm building). Theoretically I could arrive at a place where I can get those items. Thanks for this tentative direction to investigate! – montrealist Feb 27 '19 at 20:23