Mr. Jo
Mr. Jo

Reputation: 5281

CSS: Refactor grid to a flex layout with different childs

I'm currently trying to build a flex layout which should have 3 possible childs:

enter image description here

I've build this grid layout but I need change it to flex because of the compatibility of some browsers. How can I do this? I've tried a lot but the result is always bad.

.wrapper {
    width: 60%;
    display: grid;
    display: -ms-grid;
    grid-template-columns: 1fr 75px;
    text-align: center;
    position: relative;
    margin-bottom: 20px;
}

.wrapper div+div {
    margin-left: 6px;
}

.wrapper div {
    background-color: yellow;
    padding: .6em 1em;
    text-align: center;
}

.wrapper div.show.single-button {
  grid-column: 1/span 2;
}

.wrapper div.cancel {
    grid-column: 1/span 2;
    -ms-grid-row: 2;
    -ms-grid-column-span: 2;
    margin-top: 6px;
    margin-left: 0;
}
<div class="wrapper">
  <div class="show single-button">Show</div>
</div>

<div class="wrapper">
  <div class="show">Show</div>
  <div class="invoice">Invoice</div>
</div>

<div class="wrapper">
  <div class="show">Show</div>
  <div class="invoice">Invoice</div>
  <div class="cancel">Cancel</div>
</div>

Upvotes: 0

Views: 175

Answers (3)

bkis
bkis

Reputation: 2587

Flexbox offers everything you need for this. No need to hack around by mixing flexbox with box-model or width properties:

.wrapper {
  height: 100px;
  display: flex;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.wrapper > div {
  flex: 1;
  border: 1px dotted #999;
  background-color: aliceblue;
}

.wrapper > div:nth-child(2) {
  flex-shrink: 0;
  flex-grow: 0;
  flex-basis: 75px;
  -webkit-flex-basis: 75px;
}

.wrapper > div:nth-child(3) {
  flex-shrink: 0;
  flex-grow: 0;
  flex-basis: 100%;
  -webkit-flex-basis: 100%;
}
<div class="wrapper">
  <div>1</div>
</div>

<div class="wrapper">
  <div>1</div>
  <div>2</div>
</div>

<div class="wrapper">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

Upvotes: 2

arieljuod
arieljuod

Reputation: 15848

You can use flex-basis to tell the initial width of the elements and flex-grow to tell if they should take more space, and flex-wrap so it does not force them to fit in one line, something like:

.wrapper {
  display: flex;
  flex-wrap: wrap; // make it multiline
  margin-bottom: 1rem;
}

.wrapper div {
  background: yellow;
  margin: .2rem;
  padding: .2rem;
  text-align: center;
}

.invoice {
  flex-basis: 75px; // make it have 75px
  flex-grow: 0; // can't grow
  flex-shrink: 0; // can't shrink
}

.show {
  flex-grow: 1; // no basis width, just grow and take the space left from .invoice
}

.cancel {
  flex-basis: 100%; // takes the whole width so it must go on a single row
}

https://codepen.io/anon/pen/KJLqVj

Upvotes: 1

Paulie_D
Paulie_D

Reputation: 115313

Judicious use of flex:1 and flex-wrap seems to work.

* {
  box-sizing: border-box;
}

.wrapper {
  width: 60%;
  margin: auto;
  display: flex;
  flex-wrap: wrap;
  margin-bottom: 20px;
  justify-content: space-between;
  border: 1px solid green;
}

.wrapper div {
  background-color: lightblue;
  padding: .6em 1em;
  text-align: center;
  margin: 6px;
}

.wrapper div.show {
  flex: 1;
}

.wrapper div.invoice {
  flex: 1;
  max-width: 75px;
}

.wrapper div.cancel {
  flex: 1 1 100%;
}
<div class="wrapper">
  <div class="show single-button">Show</div>
</div>

<div class="wrapper">
  <div class="show">Show</div>
  <div class="invoice">Invoice</div>
</div>

<div class="wrapper">
  <div class="show">Show</div>
  <div class="invoice">Invoice</div>
  <div class="cancel">Cancel</div>
</div>

Upvotes: 2

Related Questions