0

I have been trying many different methods to achieve the following but could not.

I tried using media query to change the order of the children within the flex box of the div that contains all 3 but it seems like I can only do so when all 3 children are divs. However when all 3 children are divs, I cannot achieve the desktop outcome. Basically the header and the paragraph text will each take a column.

Any help would be greatly appreciated.

Desired flexbox outcome

Exiting code: https://codepen.io/lionellloh/pen/BawVpjm

<div class="parent">
  <img src="https://upload.wikimedia.org/wikipedia/commons/2/27/Red_square.svg"> 
  <h1> This is a header </h1> 
  <p> This is some body text that is very interesting </p> 
  
 </div>
.parent {
  display: flex;
  flex-wrap: wrap; 
}

@media only screen and (max-width: 900px) {
    .parent :nth-child(1) {
        order: 2;
    }

    .parent :nth-child(2) {
        order: 1;
    }

    .parent :nth-child(3) {
        order: 3;
    }
}

3 Answers3

0

You may like to look at grid which will allow you to name areas and assign elements to them.

Then you can redefine the areas when the max-width is at some value.

This saves having to go through all the affected elements and specify their order.

Here's a simple snippet. It puts a background color on each element so you can see which is being allocated to where.

Obviously you'll want to look at exactly the proportions you want the header to take up compared to the paragraph and so on but this is to get you started.

.container {
  display: grid;
  min-width: 600px;
  width: 25%;
  aspect-ratio: 1 / 1;
  gap: 10px;
  grid-template-areas:
    'I H'
    'I P'
    'I P'
    'I P';
  background: pink;
  grid-template-columns: 1fr 1fr;
}
h1 {
  grid-area: H;
  background: cyan;
}
img {
  grid-area: I;
  background: magenta;
  object-fit: cover;
  width: 100%;
  height: 100%;
}
p {
  grid-area: P;
  background: yellow;
}
@media (max-width: 600px) {
  .container {
    grid-template-areas:
      'H'
      'I'
      'P';
  }
}
<div class="container">
  <h1>Heading</h1>
  <img src="https://picsum.photos/id/1015/200/600">
  <p>Paragraph text<br>Paragraph text<br>Paragraph text<br>Paragraph text<br>Paragraph text<br></p>
</div>
A Haworth
  • 30,908
  • 4
  • 11
  • 14
-1

The CSS property you're looking for is (quite aptly) named order.

The order property controls the order in which flex items appear within the flex container, by assigning them to ordinal groups. It takes a single value, which specifies which ordinal group the flex item belongs to.

https://www.w3.org/TR/css-flexbox-1/#order-property

So in your example, you would explicitly set the order on all 3 elements, and then within a media query override the order for one/some of the elements to adapt to the "other" layout.


Update: I see you've updated the question but didn't really have any content at all yet. In that case i'd advise going with grid instead of flex. Which is very much alike but has a few features that make it better suited for what you describe.

You could go with something like this:

.parent {
      display:   grid;
      grid:     'heading'
                'imagearea'
                'content';
}

img { grid-area: imagearea; }
h1  { grid-area: heading;   }
p   { grid-area: content;   }


@media only screen and (max-width: 900px) {
  .parent {
    grid-template-areas:
                'imagearea heading'
                'imagearea content';
  }
}

/* unrelated CSS; just to show borders */
.parent > * { margin: 0; border: 2px solid black; background-color: #DEFFDE; }
<div class="parent">
  <h1>This is a header</h1>
  <p>This is some body text that is very interesting</p>
  <img src="https://upload.wikimedia.org/wikipedia/commons/2/27/Red_square.svg">
 </div>
Raxi
  • 2,452
  • 1
  • 6
  • 10
-1

Thank you for making suggestions that fit my skills.

<div class="parent">
  <img src="https://upload.wikimedia.org/wikipedia/commons/2/27/Red_square.svg">
  <div class="content">
    <h1> This is a header </h1> 
    <p> This is some body text that is very interesting </p> 
  </div>
</div>


 <style>
  .parent {
   display:flex;
   flex-direction:row;
   justify-content: space-between;
  }
  .content {
   display:flex;
   flex-direction:colume;
   justify-content: space-between;
   }

@media screen and (min-width:512px) {
.parent {
  display:flex;
  flex-direction:colume;
  justify-content: space-between;
 }
}
</style>

Thanks

Tyler Minegar
  • 317
  • 1
  • 5