I would like to sandwich a vertical layout between two elements for large screens (example-2) – and for small screens, have the left-most and inner-top-most elements next to each other, and then everything else below it (example-3).
But I am trying to prevent having to write two different HTML structures, which is the only way I can currently achieve this. I wonder if I can do this with flexbox.
(function(){
const toggle_butt = document.querySelector('[name="mobile"]');
const root_el = document.querySelector('.root');
if (!toggle_butt || !root_el) {
return false;
}
toggle_butt.onchange = () => {
if (root_el.classList.contains('mobile')) {
root_el.classList.remove('mobile');
} else {
root_el.classList.add('mobile');
}
};
})()
.root {
max-width: 600px;
border: 1px dashed gray;
padding: 0.25rem;
}
.root.mobile {
max-width: 320px;
}
.controller {
margin-bottom: 0.5rem;
}
[class*="example-"] + [class*="example-"] {
margin-top: 1rem;
}
.d-flex {
display: flex;
flex-wrap: wrap;
}
.red, .yellow, .green, .blue {
min-width: 50px;
min-height: 40px;
}
.red {
background-color: tomato;
}
.yellow {
background-color: gold;
height: 40px;
}
.green {
background-color: limegreen;
height: 50px;
}
.blue {
background-color: cornflowerblue;
}
/* ----------- */
.example-1 .red {
flex: 0 0 20%;
}
.example-1 .yellow {
flex: 1 0 70%;
}
.example-1 .green {
flex: 0 0 100%;
}
.example-1 .blue {
flex: 0 0 100px;
}
.root.mobile .example-1 .blue {
flex: 1 0 100%;
}
/* ----------- */
.example-2 .red {
flex: 0 0 20%;
}
.example-2 .yellow,
.example-2 .green {}
.example-2 .blue {
flex: 0 0 100px;
}
.example-2 .cheat {
flex: 1 0 50%;
}
/* ----------- */
.example-3 .red {
flex: 0 0 20%;
}
.example-3 .yellow {
flex: 1 0 70%;
}
.example-3 .green,
.example-3 .blue {
flex: 1 0 100%;
}
.example-3 .cheat {
display: flex;
flex: 1 0 100%;
}
<div class="root">
<div class="controller">
<label>
<input type="checkbox" name="mobile" />
<span class="text">mobile</span>
</label>
</div>
<div class="example-1 d-flex">
<div class="red"></div>
<div class="yellow">Can flex do it?</div>
<div class="green"></div>
<div class="blue"></div>
</div>
<div class="example-2 d-flex">
<div class="red"></div>
<div class="cheat">
<div class="yellow">Goal: desktop</div>
<div class="green"></div>
</div>
<div class="blue"></div>
</div>
<div class="example-3 d-flex">
<div class="cheat">
<div class="red"></div>
<div class="yellow">Goal: mobile</div>
</div>
<div class="green"></div>
<div class="blue"></div>
</div>
</div>
It's not important for green to line up with the bottom edge of red and blue.
Red is an image and yellow is a headline; that is why I'm trying to do this.
StackOverflow questions I looked at (but they're not quite the same):
- Flex Row space between wrapped items
- Flex Layout mixing rows and column
- What's the difference between display:inline-flex and display:flex?
- CSS webkit flex layout in both horizontal and vertical directions -- (This answer by Reggie looks promising, but I can't get this to work)