Ae Leung
Ae Leung

Reputation: 378

How to restrict the number of items in flexbox according to screen size

I am new to grid designing on website design

In my react project, I have a row showing 3 components. One is Leverage type dot selection, Two of them are input box, Loan amount and Loan Rate.

enter image description here

Right now, every things seems fine in full screen, but when I shrink it, you can see that Loan Rate is placed on the next line while Loan Amount was still on above line

enter image description here

But what I want is, when I shrink it, it is either like this(1), or like (2) when it is super small

enter image description here

In(2), basically its been achieved with my existing css, when the screen is super small

Q: How could I either showing everything in the same line or showing one line with leverage type and one line with Loan Amount and Loan Rate?

Here is my code

.setting {
  display: flex;
  justify-content: space-between;
  margin-top: 50px;
}

Upvotes: 0

Views: 644

Answers (1)

Nexo
Nexo

Reputation: 2331

  • There are many ways we can break flex item in flexbox layout the one I have used here is flex-direction:column, this property sets every flexitem to vertically..
@media(max-width:576px) {
      .flexBox {
        flex-direction: column;
        /*set all flexItem to vertically*/
        align-items: stretch;
        /* stretch will foce to take full width*/
      }
    }
  • Meaning of media(max-width:979px) means, CSS inside of that code block will only apply to screen size lessthan or equal to 979px. Means the CSS will not affect for screensize bigger than 979px.
  • Speaking about below code,
.flexBox .flexItem {
    flex: 1 0 calc(100%/var(--number-of-items-for-midium-screen) - var(--gap-val)*2)
  }
  • calc(100%/var(--number-of-items-for-midium-screen) - var(--gap-val)*2) here we divide 100% width with the number of items we want per row and we minus var(--gap-val) twice because we have applied gap:10px, which applied both side of .flexItem so we minus it 2 times.
  • And just to make CSS more friendly I have created CSS variables for --number-of-items-for-midium-screen <= Number of items in a row --gap-val <= gap between flex items in a row

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  --number-of-items-for-midium-screen: 2;
  /*Number of items you want in medium screen(below 979px)*/
  --gap-val: 10px;
  /*Gap you want between flex items*/
}

.flexBox {
  display: flex;
  align-items: center;
  gap: var(--gap-val);
  margin: 10px;
}

.flexBox .flexItem {
  flex: 1;
  border: 2px solid #d6d6d6;
  padding: 10px;
}

@media(max-width:979px) {
  .flexBox {
    flex-wrap: wrap;
  }
  .flexBox .flexItem {
    flex: 1 0 calc(100%/var(--number-of-items-for-midium-screen) - var(--gap-val)*2)
  }
}

@media(max-width:576px) {
  .flexBox {
    flex-direction: column;
    /*set all flexItem to vertically*/
    align-items: stretch;
    /* stretch will foce to take full width*/
  }
}
<div class="flexBox">
  <div class="flexItem">
    <p>Leverage type</p>
    <label for="static">static</label>
    <input type="radio" value="static" id="static" name="gp1" />
    <label for="dynamic">dynamic</label>
    <input type="radio" value="static" id="dynamic" name="gp1" />
  </div>
  <div class="flexItem">
    <label for="loanRate">Loan Rate</label>
    <input id="loanRate" type="text" />
  </div>
  <div class="flexItem">
    <label for="loanAmount">Loan Amount</label>
    <input id="loanAmount" type="text" />
  </div>
</div>

Understanding how to break layouts in flexbox

const btn1 = document.querySelector("#btn1"),
  btn3 = document.querySelector("#btn3"),
  btn4 = document.querySelector("#btn4");
const flexBox = document.querySelectorAll(".flexBox")[0];
const flexItems = document.querySelectorAll(".flexBox .flexItem");
const preview = document.querySelectorAll(".preview")[0];
btn1.onclick = () => {
  flexBox.style.flexDirection = "column";
  preview.style.display = "block";
  preview.innerHTML = `.flexBox{flex-direction:column;}`;
}
btn3.onclick = () => {
  flexItems.forEach(flexItem => {
    flexItem.style.flex = "1";
  })
  preview.style.display = "block";
  preview.innerHTML = `.flexItems{flex:1;}`;
}
btn4.onclick = () => {
  const numberofItems = +document.querySelector("#numberofItems").value;
  if (numberofItems && numberofItems >= 1 && numberofItems <= 6) {
    flexBox.style.flexFlow = "initial";
    flexBox.style.flexWrap = "wrap";
    flexItems.forEach(flexItem => {
      flexItem.style.flex = `1 0 calc(100%/${numberofItems})`;
    })
    preview.style.display = "block";
    preview.innerHTML = `.flex{flex-wrap:wrap;}</br>.flexItems{flex:1 0 calc(100%/${numberofItems});}`;
  } else {
    alert("Please enter number of items you need from 1 to 6");
  }
}
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.flexBox {
  display: flex;
}

.flexItem {
  display: inline-block;
  height: 100px;
}

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

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

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


/*Just for styling*/

.buttons {
  margin-top: 10px;
}

.buttons button {
  padding: 10px;
  border: 2px solid #000;
  background: #fff;
  text-transform: capitalize;
  margin: 10px;
}

.textInput {
  display: flex;
  gap: 5px;
  margin: 10px;
}

.textInput input {
  flex: 1 0 75%;
}

.textInput button {
  padding: 5px;
  margin: 0;
}

.preview {
  width: 100%;
  border: 2px solid #000;
  display: none;
  padding: 30px;
}
<div class="flexBox">
  <div class="flexItem bg-red">
    <h5>This is flex box item</h5>
  </div>
  <div class="flexItem bg-blue">
    <h5>This is flex box item</h5>
  </div>
  <div class="flexItem bg-green">
    <h5>This is flex box item</h5>
  </div>
  <div class="flexItem bg-red">
    <h5>This is flex box item</h5>
  </div>
  <div class="flexItem bg-blue">
    <h5>This is flex box item</h5>
  </div>
  <div class="flexItem bg-green">
    <h5>This is flex box item</h5>
  </div>
</div>
<div class="buttons">
  <button id="btn1">Apply flex-direction to column</button>
  <button id="btn3">set all box equal size</button>
  <div class="textInput">
    <input type="number" id="numberofItems" placeholder="Enter the number of items you want in a row" min="1" max="6">
    <button id="btn4">set items in a row</button>
  </div>
</div>
<div class="preview">
  <h2>Applied css</h2>
</div>

Upvotes: 1

Related Questions