ajor
ajor

Reputation: 1634

CSS: Distribute <div>s or <li>s vertically with even space

I want to distribute 4 lines of text in boxes vertically and evenly across the length of a div whose height is set to 50% of the containing div (i.e. no fixed height). I want the layout to look like this:

enter description here

According to the current plan there will be four of these boxes, but this may change in future so ideally the solution would allow for more or less than four. I would like a CSS only solution if possible.

So far I have ignored the graphic, and have tried various options to get the boxes aligned as I would like.

Here is the best I have so far, which is approximate but still doesn't align as I want.

.box-green, .box-red, .box-yellow, .box-blue{
  padding:7px;
  width:100%;
}

.box-green {
  background-color:green;
}

.box-red {
  background-color:red;
}

.box-yellow {
  background-color:yellow;
}

.box-blue {
  background-color:blue;
}

div {
  background-color:grey;
  height:50%;
  margin: auto 10% auto auto;
  position: absolute;
  right:0;
  text-align:right;
  top:50%;
  transform:translateY(-50%);
}

ul {
  display:table;
  height:100%;
}

li {
  display:table-row;
  width:100%;
}
<div>
<ul>
<li><span class="box-green">Line 1</span></li>
<li><span class="box-red">Second line of text</span></li>
<li><span class="box-yellow">3rd line</span></li>
<li><span class="box-blue">Even more text</span></li>
</ul>
</div>

I will then need to add some sort of table formatting, I guess, to each row in order to distribute the graphic and text appropriately.

I hope I've been able to explain the problem clearly.

Upvotes: 3

Views: 10516

Answers (2)

Danield
Danield

Reputation: 125453

With flexbox this is easy.

Just set the following properties on the container:

ul {
      display: flex;
      flex-direction: column;
      justify-content: space-between;
}

FIDDLE (Resize browser height to see this in action)

.box-green,
.box-red,
.box-yellow,
.box-blue {
  padding: 7px;
  width: 100%;
  box-sizing: border-box;
}
.box-green {
  background-color: green;
}
.box-red {
  background-color: red;
}
.box-yellow {
  background-color: yellow;
}
.box-blue {
  background-color: blue;
}
ul {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 0;
  margin: 0;
  list-style: none;
  background-color: grey;
  height: 50vh;
}
<ul>
  <li class="box-green">Line 1</li>
  <li class="box-red">Second line of text</li>
  <li class="box-yellow">3rd line</li>
  <li class="box-blue">Even more text</li>
</ul>

Upvotes: 9

dognose
dognose

Reputation: 20899

Well, even if people hare going to hate me for this answer - but if you want to achieve a table-like behaviour - why not simply use a table which serves everything you need out of the box?

<div>
<table>
    <tr>
        <td class="box-yellow">first</td>
    </tr>
    <tr>
        <td class="box-green">Second</td>
    </tr>
    <tr>
        <td class="box-blue">Third</td>
    </tr>
    <tr>
        <td class="box-red">fourth</td>
    </tr>
    </table>
</div>

http://jsfiddle.net/166d5qgp/1/

if you don't want the boxes to cover (in this example) about 25% of height, place a div into the td, and you are done. Play a little bit with the margin and padding to achieve the exact look desired:

<div id="outer">
<table>
    <tr>
        <td><div class="box-yellow">first</div></td>
    </tr>
    <tr>
        <td><div class="box-green">Second</div></td>
    </tr>
    <tr>
        <td><div class="box-blue">Third</div></td>
    </tr>
    <tr>
        <td><div class="box-red">fourth</div></td>
    </tr>
</table>
</div>

http://jsfiddle.net/e97tmr8u/

Upvotes: 2

Related Questions