4

I have a container with many items inside.

I would like to display them alternatively on a single row (with eventually an horizontal scrollbar on container) or wrapped in multiple rows.

I thought to use Flexbox Layout module. Two examples are visible in this here:

.single-line {
  border: solid 1px blue;
  width: 50%;
  overflow-x: scroll;
}
.wrap-line {
  border: solid 1px green;
  width: 50%;
}
ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}
.single-line ul {
  flex-wrap: nowrap;
}
.wrap-line ul {
  flex-wrap: wrap;
}
li {
  display: block;
  width: 40px;
  height: 40px;
  background: gray;
  text-align: center;
  border: solid 1px red;
  line-height: 40px;
}
<div class="single-line">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
  </ul>
</div>

<br>

<div class="wrap-line">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
  </ul>
</div>

jsFiddle:

The most important code is the following:

ul {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}

.single-line ul {
  flex-wrap: nowrap;
}

.wrap-line ul {
  flex-wrap: wrap;
}

It is close to what I would like but there are some issues:

  1. First example shrinks inner blocks, so the container is not scrollable. How to solve that?

  2. In the second example, how do I add vertical separation between lines but not at the edges of the container? I thought about margin-bottom on each LI but this is not the right solution (and I can't set a fixed height for container)

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Luca Detomi
  • 5,564
  • 7
  • 52
  • 77
  • 1
    Are you trying to make something like a grid? If do, you can use a little hack: fill the grid with empty divs with the same width of the columns (the divs must be equal to max columns that the grid will have - 1). Check [this fiddle](https://jsfiddle.net/guzgarcia/n7j7afma/1/) (resize the output). –  Dec 21 '16 at 15:00
  • 1
    It's an interesting solution, not one that I need but surely someone could find it useful – Luca Detomi Dec 21 '16 at 15:10
  • 1
    Please don't ask multiple questions in the same question – Oriol Dec 21 '16 at 17:28
  • 1
    BTW, for the second question see [Flexbox: how to add margin / vertical spacing for the case there is more than one row?](http://stackoverflow.com/q/31844421/1529630) – Oriol Dec 21 '16 at 17:52

2 Answers2

1

I've made something like this: https://jsfiddle.net/yduhj30L/18/ flex-shrink: 0 makes that flex element can overflow.

On second I set margin-top only to one element and set position to flex-end for each.

Edit: align items to flex-start makes scrolled items accessible.

Luca Detomi
  • 5,564
  • 7
  • 52
  • 77
Ula
  • 594
  • 2
  • 6
  • 18
  • Thanks for `flex-shrink: 0` solution. Please, can you explain me why `flex-end` allows to have the entire second row spaced from the first one? And in case of more than 2 rows? – Luca Detomi Dec 21 '16 at 13:37
  • with flex-end element are positioned to bottom line of container and margin keep the first line to the top. – Ula Dec 21 '16 at 13:40
  • Ok, great, but this runs correctly only if wrap is into 2 rows. In case of 3 or more... it does not results in a good layout... :-( – Luca Detomi Dec 21 '16 at 13:43
  • @LucaDetomi Maybe something like this: https://jsfiddle.net/yduhj30L/19/ – Ula Dec 21 '16 at 13:53
  • Almost, very near. Just a little vertical margin between each row, excluding at container edges – Luca Detomi Dec 21 '16 at 14:02
1

You have already answers for the first question.

About the second, all you need is a little trick.

Set margin top on all the items.

To hide this margin for the first row, set a negative margin of the same amount for the ul. Since you have an outer container, the ul sits outside this container in the amount needed for the upper magin to be invisible

hover the ul to shrink it and test it

.wrap-line {
  border: solid 1px green;
  width: 70%;
  transition: width 5s;
}

.wrap-line:hover {
  width: 30%;  
}
ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}
.wrap-line ul {
  flex-wrap: wrap;
  margin-top: -10px; /* added */
}
li {
  display: block;
  width: 40px;
  height: 40px;
  background: gray;
  text-align: center;
  border: solid 1px red;
  line-height: 40px;
  margin-top: 10px; /* added */
}
<div class="wrap-line">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
  </ul>
</div>
vals
  • 61,425
  • 11
  • 89
  • 138