CSS flexbox, changing box positions below breakpoint

Viewed 55

I have a flexbox parent with 4 children, the code as follows:

#technologiesFlexContainer {
  display: flex;
  margin-top: 1rem;
  background-color: black;
}
.techFlexClass {
  flex: 1 0;
  width: auto;
  display: grid;
  grid-template-columns: 100%;
  grid-template-rows: 20% 60% 20%;
  justify-items: center;
  height: 20rem;
  overflow: hidden;
}
.techHeader {
  grid-area: 1 / 1 / 2 / 2;
  align-self: end;
  z-index: 2;
}
.techBody {
  grid-area: 2 / 1 / 3 / 2;
  align-self: center;
  z-index: 2;
  max-width: 13rem;
  text-align: center;
}
.techButton {
  grid-area: 3 / 1 / 4 / 2;
  align-self: start;
  z-index: 2;
}
#techFlexChild1 {
  order: 1;
}
#techFlexChild2 {
  order: 2;
}
#techFlexChild3 {
  order: 3;
}
#techFlexChild4 {
  order: 4;
}
.techImage {
  grid-area: 1 / 1 / 4 / 2;
  z-index: 1;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  opacity: 50%;
  transition: width 0.5s, height 0.5s;
  transition-timing-function: linear;
}
.techFlexClass:hover img {
  width: 105%;
  height: 105%;
}

@media only screen and (min-width: 1200px) {}

@media only screen and (max-width: 1200px) {}
<div id="technologiesFlexContainer">
  <div id="techFlexChild1" class="techFlexClass">
    <h3 class="techHeader">HEAD1</h3>
    <p class="techBody">BODY1</p>
    <a class="button1 techButton" href="#">Learn More</a>
    <img class="techImage" src="content/images/homepage/IMG1.png">
  </div>
  <div id="techFlexChild2" class="techFlexClass">
    <h3 class="techHeader">HEAD2</h3>
    <p class="techBody">BODY2</p>
    <a class="button1 techButton" href="#">Learn More</a>
    <img class="techImage" src="content/images/homepage/IMG2.png">
  </div>
  <div id="techFlexChild3" class="techFlexClass">
    <h3 class="techHeader">HEAD3</h3>
    <p class="techBody">BODY3</p>
    <a class="button1 techButton" href="#">Learn More</a>
    <img class="techImage" src="content/images/homepage/IMG3.png">
  </div>
  <div id="techFlexChild4" class="techFlexClass">
    <h3 class="techHeader">HEAD4</h3>
    <p class="techBody">BODY4</p>
    <a class="button1 techButton" href="#">Learn More</a>
    <img class="techImage" src="content/images/homepage/IMG4.png">
  </div>
</div>

See codepen here: https://codepen.io/roomwillow/pen/mdOMvzG

When the page is 1200px or wider, I want the flexbox to remain exactly how you see it in the code here: 4 equal boxes side by side by side by side. But when the page is 1200px or smaller, I want it to change into the first two boxes side by side on row 1, and the second two boxes side by side on row 2.

You'll notice the boxes are equal width no matter the page width right now, and I want it to remain that way at all points in the breakpoint. Any suggestions on how I could achieve this using media queries?

1 Answers

Right now your flex container doesn't allow wrapping, which is the default. All you have to do is set flex-wrap: wrap in your media query. That'll cause your flex items to start to wrap when they get to the point where they'd have to start shrinking to fit inside the container.

Then to specify the width of the items you can either use flex-basis (third value of the flex shorthand property) or width, whichever.

So here's your media query:

@media only screen and (max-width: 1200px) {
  #technologiesFlexContainer {
    flex-wrap: wrap;
  }
  .techFlexClass {
    flex: 1 0 50%;
  }
}

See it in action:

#technologiesFlexContainer {
  display: flex;
  margin-top: 1rem;
  background-color: black;
}
.techFlexClass {
  flex: 1 0;
  width: auto;
  display: grid;
  grid-template-columns: 100%;
  grid-template-rows: 20% 60% 20%;
  justify-items: center;
  height: 20rem;
  overflow: hidden;
}
.techHeader {
  grid-area: 1 / 1 / 2 / 2;
  align-self: end;
  z-index: 2;
}
.techBody {
  grid-area: 2 / 1 / 3 / 2;
  align-self: center;
  z-index: 2;
  max-width: 13rem;
  text-align: center;
}
.techButton {
  grid-area: 3 / 1 / 4 / 2;
  align-self: start;
  z-index: 2;
}
#techFlexChild1 {
  order: 1;
}
#techFlexChild2 {
  order: 2;
}
#techFlexChild3 {
  order: 3;
}
#techFlexChild4 {
  order: 4;
}
.techImage {
  grid-area: 1 / 1 / 4 / 2;
  z-index: 1;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  opacity: 50%;
  transition: width 0.5s, height 0.5s;
  transition-timing-function: linear;
}
.techFlexClass:hover img {
  width: 105%;
  height: 105%;
}

/* @media only screen and (min-width: 1200px) {} */

@media only screen and (max-width: 1200px) {
  /* below here is new */
  #technologiesFlexContainer {
    flex-wrap: wrap;
  }
  .techFlexClass {
    flex: 1 0 50%;
  }
}
<div id="technologiesFlexContainer">
  <div id="techFlexChild1" class="techFlexClass">
    <h3 class="techHeader">HEAD1</h3>
    <p class="techBody">BODY1</p>
    <a class="button1 techButton" href="#">Learn More</a>
    <img class="techImage" src="content/images/homepage/IMG1.png">
  </div>
  <div id="techFlexChild2" class="techFlexClass">
    <h3 class="techHeader">HEAD2</h3>
    <p class="techBody">BODY2</p>
    <a class="button1 techButton" href="#">Learn More</a>
    <img class="techImage" src="content/images/homepage/IMG2.png">
  </div>
  <div id="techFlexChild3" class="techFlexClass">
    <h3 class="techHeader">HEAD3</h3>
    <p class="techBody">BODY3</p>
    <a class="button1 techButton" href="#">Learn More</a>
    <img class="techImage" src="content/images/homepage/IMG3.png">
  </div>
  <div id="techFlexChild4" class="techFlexClass">
    <h3 class="techHeader">HEAD4</h3>
    <p class="techBody">BODY4</p>
    <a class="button1 techButton" href="#">Learn More</a>
    <img class="techImage" src="content/images/homepage/IMG4.png">
  </div>
</div>

Related