EmptySnake
EmptySnake

Reputation: 129

Flexbox space around (cross browser)

I use this css to evenly distribut items in a column with an equal space around them.

body {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  margin: 0;
}

.body {
  position: relative;
  height: 500px;
}

.body .header, .body .footer  {
  position: absolute;
  color: white;
  text-align: center;
  left: 0;
  right: 0;
}

.body .header {
  background-color: red;
  top: 0;
}

.body .footer {
  background-color: blue;
  bottom: 0;
}

.body .content {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
	-ms-box-orient: vertical;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -moz-flex;
  display: -webkit-flex;
  display: flex;
  -webkit-justify-content: space-around; 
  justify-content: space-around; 
  flex-direction: column;
  height: 100%;
  padding: 18px 0 18px;
}

.content > div {
  background-color: yellow;
  text-align: center;
}
<div class="body">
  <div class="header">
    HEADER
  </div>
  
  <div class="content">
    <div style="height: 15px;">1</div>
    <div style="height: 25px;">2</div>
    <div style="height: 15px;">3</div>
    <div style="height: 20px;">4</div>
  </div>
  
  <div class="footer">
    FOOTER
  </div>
</div>

But this dosn't work in IE9. Can someone share a cross browser solution for this task (equal space between items vertically)? Please)

P.S. Item's height in content block NOT fixed and NOT same. Content block's height will be 100% of viewport.

Upvotes: 0

Views: 332

Answers (4)

Rounin
Rounin

Reputation: 29491

One non-flexbox approach would be to use javascript - which is a bit of a hack but it does the job.

The javascript below:

  • counts the number of child divs in .content
  • calculates what the top margin of each child div ought to be
  • applies the top margin to each child div
  • when the window is resized, recalculates the top margin

function calculateMargins() {
    var header = document.getElementsByClassName('header')[0];
    var footer = document.getElementsByClassName('footer')[0];
    var content = document.getElementsByClassName('content')[0];
    var contentChildren = content.getElementsByTagName('div');

    var bodyHeight = window.innerHeight;
    var headerHeight = parseInt(window.getComputedStyle(header).height);
    var footerHeight = parseInt(window.getComputedStyle(footer).height);

    var contentChildrenHeightsCombined = 0;

    for (var i = 0; i < contentChildren.length; i++) {
        contentChildrenHeightsCombined += parseInt(window.getComputedStyle(contentChildren[i]).height);
    }

    var margin = ((bodyHeight - headerHeight - footerHeight - contentChildrenHeightsCombined) / (contentChildren.length + 1));

    for (var i = 0; i < contentChildren.length; i++) {
        contentChildren[i].style.marginTop = margin + 'px';
    }
}

window.addEventListener('load', calculateMargins, false);
window.addEventListener('resize', calculateMargins, false);
body {
margin: 0;
overflow: hidden;
}

.header, .footer {
position: absolute;
left: 0;
width: 100%;
height: 20px;
color: white;
text-align: center;
}

.header {
background-color: red;
top: 0;
}

.footer {
background-color: blue;
top: calc(100vh - 20px);
z-index: 12;
}

.content {
position: absolute;
display: table;
top: 20px;
width: 100%;
height: calc(100vh - 20px - 20px);
background-color: orange;
}

.content > div {
display: inline-block;
width: 100%;
background-color: yellow;
text-align: center;
}
<div class="header">HEADER</div>
  
<div class="content">
<div style="height: 15px; line-height: 15px;">1</div>
<div style="height: 25px; line-height: 25px;">2</div>
<div style="height: 15px; line-height: 15px;">3</div>
<div style="height: 20px; line-height: 20px;">4</div>
</div>
  
<div class="footer">FOOTER</div>

Upvotes: 0

GvM
GvM

Reputation: 1733

check this if it fits your needs.

.content {
  height: 400px;
  width: 100%;
  display: table;
}

.content > .tablerow {
  display: table-row;
  text-align: center;
}

.content > .tablerow > .tablecell {
  display: table-cell;
  vertical-align: middle;
  height: 10px;
}
.content > .tablerow > .tablecell > .somecontents {
  background: red;
}
<div class="content">
  <div class="tablerow">
    <div class="tablecell"><div class="somecontents">your contents</div></div>
  </div>
   <div class="tablerow">
    <div class="tablecell"><div class="somecontents">your contents</div></div>
  </div>
   <div class="tablerow">
    <div class="tablecell"><div class="somecontents">your contents</div></div>
  </div>
   <div class="tablerow">
    <div class="tablecell"><div class="somecontents">your contents</div></div>
  </div>
</div>

Upvotes: 1

Josh Pittman
Josh Pittman

Reputation: 7324

Turn your flex container into a table. Then turn each column item into a table cell and align them all to the centre.

.container {
    display: table;
}

.item {
    display: table-cell;
    text-align: center;
}

Since ie9 doesn't support flexbox, you will either have to write a separate ie9 only stylesheet using <!--[if IE 9]><![endif]--> or you could place the flex attributes after the table attributes in your stylesheet.

For example...

 .container {
        display: table;
        display: flex;
    }

Anything above ie9 will follow display:flex since it is comes after display:table, but ie9 won't know what display:flex means so it will fallback to display:table.

You can find a bunch of other useful ways to recreate flexbox effects without using flexbox here: https://kyusuf.com/post/almost-complete-guide-to-flexbox-without-flexbox

Upvotes: 0

itacode
itacode

Reputation: 3787

Flex is not supported by ie9 caniuse so you should use JS or simply with equal vertical margins as they collapse.

Upvotes: 1

Related Questions