Flex CSS with fixed width and equal height - html

I have three sections in a container. When I resize my browser to the max-width of 668px, I need to make the section 1 and section 3 in one row and the section 2 in the below row. The section 2 width should be proportional to the section 1 and section 3 width.
But now once I minimize the browser size to 668px and below, then section 3 is not visible.
This is what I tried.
#media (max-width: 668px) {
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-self: flex-start;
}
.container .section1 {
height: 300px;
}
.container .section1,
.container .section3 {
flex: 0 0 262px;
margin: 3px;
display: block;
flex-grow: 0;
flex-shrink: 0;
}
.container .section2 {
flex: 0 0 500px;
flex-grow: 0;
flex-shrink: 0;
order: 1;
min-height: 235px;
}
}
#media (max-width: 940px) {
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-self: flex-start;
}
.container .section1 {
height: 300px;
}
.container .section1,
.container .section3 {
flex: 0 0 262px;
margin: 3px;
display: block;
flex-grow: 0;
flex-shrink: 0;
}
.container .section2 {
flex: 0 0 500px;
flex-grow: 0;
flex-shrink: 0;
order: 1;
min-height: 235px;
}
}
<div class="container">
<div class="section1">Section 1</div>
<div class="section2">Section 2</div>
<div class="section3">Section 3</div>
</div>

You don't have any height specified on .section3.
On .section1 you have height: 300px.
On .section2 you have min-height: 235px.
But on .section3 you have nothing. Try this adjustment to your code:
.section1, .section3 {
height: 300px;
}
jsFiddle demo

Related

Flex child wrapping when it shouldn't; flex-wrap: nowrap not working

No idea why, but flex-flow: row nowrap doesn't seem to be preventing the orange div from wrapping. The green and orange divs should be side by side - what am I doing wrong here? The orange div also seems to have no height.
Any help would be appreciated here, thank you.
.appShopSummaryContainer {
display: flex;
flex-flow: column wrap;
}
.appShopSummaryProductWrap {
flex-basis: 100%;
width: 100%;
background: pink;
flex-flow: row nowrap;
display: flex;
}
.appShopSummaryImg {
flex-basis: 40%; /* flex: 0 0 40% */
width: 40%;
height: auto;
padding-bottom: 26.667%;
background: green;
}
.appShopSummaryInfo {
flex-basis: 60%; /* flex: 0 0 60% */
width: 60%;
background: orange;
height: 100%;
}
<div class='appShopSummaryContainer'>
<div class='appShopSummaryProductWrap'>
<a href='#'><div class='appShopSummaryImg'></div>erg</a>
<div class='appShopSummaryInfo'>wgh</div>
</div>
<div class='appShopSummaryProductWrap'>
<a href='#'><div class='appShopSummaryImg'></div>jyu</a>
<div class='appShopSummaryInfo'>erge</div>
</div>
</div>
you can try out this code
<div class="appShopSummaryContainer">
<div class="appShopSummaryProductWrap">
<div class="appShopSummaryInfo"></div>
</div>
</div>
</br>
<div class='appShopSummaryContainer'>
<div class='appShopSummaryProductWrap'>
<a href='#'class='appShopSummaryImg' ><div>test</div></a>
<div class='appShopSummaryInfo'>test1</div>
</div>
</div>
css goes here
.appShopSummaryContainer {
display: flex;
flex-flow: column wrap;
}
.appShopSummaryProductWrap {
flex-basis: 100%;
background: pink;
height:100%;
width:100%;
display: flex;
flex-flow: row nowrap;
}
.appShopSummaryImg {
flex-basis: 40%; /* flex: 0 0 40% */
width: 40%;
height: auto;
padding-bottom: 26.667%;
background: green;
}
.appShopSummaryInfo {
flex-basis: 60%; /* flex: 0 0 60% */
width: 60%;
background: orange;
padding-bottom: 26.667%;
height: 100%;
}

Split in half vertically and horizontally second flex item

Can please someone point me out how can I split out second flex item vertically and horizontally like I have in image below ?
I managed to split in half one big box but I failed making it the same for second flex item.
This is what I have right now -> https://jsfiddle.net/paveu/8c9Ls5s8/
Thanks,
HTML
<div class="desktop">
<div class="yellow">lorem</div>
<div class="orange">lorem</div>
<div class="purple">lorem</div>
<div class="green">lorem</div>
</div>
CSS
* {
box-sizing: border-box;
}
main,
div {
display: flex;
padding: 1rem;
}
.desktop {
flex-direction: column;
flex-wrap: wrap;
height: 400px;
width: 100%;
align-items: center;
justify-content: center;
align-content: stretch;
}
.desktop > div {
flex: 1;
}
div.orange {
background-color: #FFAD77;
width: 30%;
flex: 0 0 70%;
margin-left: 10px;
}
div.yellow {
flex: 0 0 100%;
width: 70%;
background-color: #FFE377;
}
div.purple {
width: 30%;
margin-left: 10px;
background-color: #FF77C8;
}
#media(max-width: 480px) {
.desktop > div {
flex: 1;
width: 100%;
margin: 0 auto;
}
div.orange {
order: -1;
flex: 2;
}
div.yellow {
flex: 5;
}
div.purple {
flex: 1;
}
}
Try this tell me if there is a problem in my answer
html:
<div class="desktop">
<div class="yellow">lorem</div>
<div class="orange">lorem</div>
<div class="purple">lorem</div>
<div class="green">lorem</div>
</div>
css:
* {
box-sizing: border-box;
}
main,
div {
display: flex;
padding: 1rem;
}
.desktop {
flex-direction: column;
flex-wrap: wrap;
height: 400px;
width: 100%;
}
div {
flex: 1;
}
div.orange {
background-color: #FFAD77;
width: 30%;
flex: 0 0 50%;
}
div.yellow {
flex: 0 0 100%;
width: 40%;
background-color: #FFE377;
}
div.purple {
flex: 0 0 50%;
width: 30%;
background-color: #FF77C8;
}
div.green{
background-color: green;
width:30%;
}
#media(max-width: 480px) {
.desktop div {
flex: 1;
width: 100%;
}
div[orange] {
order: -1;
flex: 2;
}
div[yellow] {
flex: 5;
}
div[purple] {
flex: 1;
}
div[purple] {
flex: 6;
}
}
output:

How to stretch div to full height with flex

How do I stretch the divs with a yellow background to full height? It should cover up the green but it is not working. I tried adding height: 100% on it but then it adds up the height from the search bar?
https://jsfiddle.net/nuy20j1h/
.block {
width: 80%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.sidebar {
height: 600px;
width: 25%;
background: red;
}
.home {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
width: 75%;
background: green;
}
.search-bar {
width: 100%;
padding: 25px;
background: blue;
}
.content-wrap {
display: flex;
flex-wrap: wrap;
width: 100%;
align-items: flex-stretch;
}
.content,
.single {
width: 50%;
background: yellow;
}
<div class="block">
<div class="sidebar">sidebar</div>
<div class="home">
<div class="search-bar">search bar</div>
<div class="content-wrap">
<div class="content">lorem ipsum</div>
<div class="single">test</div>
</div>
</div>
</div>
First you should add a style reset, I'm using this now * {} as you can se below. The trick here is to run flex-direction: column; on .home and you can tell .content-wrap to take up the rest of that space after the search with flex-grow: 1;
box-sizing: border-box; is, if you add let's say width: 200px; to a element, and add padding: 20px;, the element will stay 200px with the padding included. If you don't have that, it will take up 200px + 40px.
if you want the fiddle, here it is
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.block {
width: 80%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.sidebar {
height: 600px;
width: 25%;
background: red;
}
.home {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: flex-start;
width: 75%;
background: green;
}
.search-bar {
width: 100%;
padding: 25px;
background: blue;
}
.content-wrap {
display: flex;
flex-grow: 1;
flex-wrap: wrap;
width: 100%;
align-items: flex-stretch;
}
.content,
.single {
width: 50%;
background: yellow;
}
<div class="block">
<div class="sidebar">sidebar</div>
<div class="home">
<div class="search-bar">search bar</div>
<div class="content-wrap">
<div class="content">lorem ipsum</div>
<div class="single">test</div>
</div>
</div>
</div>
As mentioned in other answers, there is one main issue here:
flex-direction: column;, which I added to home, to enable the usage of flex properties instead of height, to make the .content-wrap fill the available space left in home
That will make the .search-bar and .content-wrap stack vertical, and enable the use of flex: 1 on .content-wrap, which will make it fill the remaining space/height.
So even if you got answers already, and since there are some properties with wrong value, or not needed, I decided to post an answer to clarify the changes made.
See my notes made in the CSS for further clarifications and what I changed.
Stack snippet
.block {
width: 80%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.sidebar {
height: 600px;
width: 25%;
background: red;
}
.home {
display: flex;
flex-direction: column; /* added */
/*flex-wrap: wrap; removed, not needed */
/*align-items: flex-start; removed, items should fill parent's,
in this changed case, width */
width: 75%;
background: green;
}
.search-bar {
/*width: 100%; not needed, default for column
item is to fill parent width as
its "align-items" is "stretch" */
padding: 25px;
background: blue;
}
.content-wrap {
flex: 1; /* added, take the remaining space left
left of its parent (height in this case) */
display: flex;
flex-wrap: wrap;
/*width: 100%; not needed, default for column
item is to fill parent width as
its "align-items" is "stretch" */
/*align-items: flex-stretch; wrong value, should be "stretch",
though since that is the default,
it is not needed */
}
.content,
.single {
width: 50%;
background: yellow;
}
<div class="block">
<div class="sidebar">sidebar</div>
<div class="home">
<div class="search-bar">search bar</div>
<div class="content-wrap">
<div class="content">lorem ipsum</div>
<div class="single">test</div>
</div>
</div>
</div>
flex-direction: column; is your friend. Here is a reworked fiddle of your code: https://jsfiddle.net/vsjktmms/1/
Using the same HTML structure you provided:
.block {
display: flex;
width: 80%;
margin: 0 auto;
background-color: gray;
align-items: stretch;
}
.sidebar {
width: 25%;
height: 600px;
background-color: red;
}
.home {
display: flex;
flex-direction: column;
align-items: stretch;
width: 75%;
background-color: green;
}
.search-bar {
padding: 25px;
background-color: blue;
}
.content-wrap {
flex: 1 1 auto;
display: flex;
flex-wrap: wrap;
width: 100%;
background-color: pink;
}
.content,
.single {
width: 50%;
background: yellow;
}

Flexbox children, mix of rows and columns

I am using flexbox to align my 4 elements in a row.
I then want to break this down for mobile like so:
I have successfully reordered the elements here:
.flexcontainer {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-align-items: flex-start;
align-items: flex-start;
width: 90%;
margin: 0 auto;
background: red;
}
.flexcontainer>div {
height: 100px;
width: 25%;
background-color: #E46119;
border: 1px solid #626262;
margin: 3px;
}
.flexcontainer>div:nth-of-type(1) {
-webkit-flex: 1 0 0;
flex: 1 0 0;
order: 3;
}
.flexcontainer>div:nth-of-type(2) {
-webkit-flex: 2 0 0;
flex: 2 0 0;
order: 2;
}
.flexcontainer>div:nth-of-type(3) {
-webkit-flex: 2 0 0;
flex: 2 0 0;
order: 1;
}
.flexcontainer>div:nth-of-type(4) {
-webkit-flex: 1 0 0;
flex: 1 0 0;
order: 4;
}
<div class="flexcontainer">
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
</div>
But I am stuck on how to break down child elements "two" and "three" into their own rows. And then how to make element "one" and "four" each 50% wide on their own row.
Is what I'm trying to do possible without additional HTML markup? Thanks for your advice.
.flexcontainer {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-align-items: flex-start;
align-items: flex-start;
width: 90%;
margin: 0 auto;
background: red;
}
.flexcontainer>div {
height: 100px;
width: 25%;
background-color: #E46119;
border: 1px solid #626262;
margin: 3px;
}
.flexcontainer>div:nth-of-type(1) {
-webkit-flex: 1 0 0;
flex: 1 0 0;
}
.flexcontainer>div:nth-of-type(2) {
-webkit-flex: 2 0 0;
flex: 2 0 0;
}
.flexcontainer>div:nth-of-type(3) {
-webkit-flex: 2 0 0;
flex: 2 0 0;
}
.flexcontainer>div:nth-of-type(4) {
-webkit-flex: 1 0 0;
flex: 1 0 0;
}
<div class="flexcontainer">
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
</div>
The desktop-mobile transition can be achieved with CSS only using flexbox.
No changes are necessary in the HTML.
.flexcontainer {
display: flex;
width: 90%;
margin: 0 auto;
background: red;
}
.flexcontainer > div {
flex: 0 0 25%;
height: 100px;
background-color: #E46119;
border: 1px solid #626262;
margin: 3px;
}
.flexcontainer > div:nth-of-type(1) { flex: 1 0 0; }
.flexcontainer > div:nth-of-type(2) { flex: 2 0 0; }
.flexcontainer > div:nth-of-type(3) { flex: 2 0 0; }
.flexcontainer > div:nth-of-type(4) { flex: 1 0 0; }
#media screen and ( max-width: 500px) {
.flexcontainer { flex-wrap: wrap; }
.flexcontainer > div:nth-of-type(1) { order: 3; flex-basis: 34%; }
.flexcontainer > div:nth-of-type(2) { order: 2; flex-basis: 70%; }
.flexcontainer > div:nth-of-type(3) { order: 1; flex-basis: 70%; }
.flexcontainer > div:nth-of-type(4) { order: 4; flex-basis: 34%; }
}
<div class="flexcontainer">
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
</div>
jsFiddle demo
How it works
The media query kicks in when the screen is 500px or less.
The order property sets the order of items on the screen. The default value is 0 for all items.
With flex-wrap: wrap on the container, flex items can now wrap.
With flex-grow set to a positive integer, there's no need for flex-basis to be precise. Since flex-grow will consume free space on the row, flex-basis only needs to be large enough to force a wrap.
If a precise flex-basis value is preferred, any borders, padding and margins would need to be factored in, maybe using box-sizing: border-box and/or calc (example).
You could group "three" and "two" into their own flex box and use flex-wrap to achieve this.
Here is a JSFiddle: https://jsfiddle.net/zw10dzzn/3/
You may have to play around with the margins and the order to get exactly the layout you want.
.flex-container {
display: flex;
align-items: flex-start;
width: 90%;
margin: 0 auto;
background: red;
flex-wrap: wrap; /* allow elements to wrap in mobile view */
}
.flex-container .one,
.flex-container .two-and-three,
.flex-container .four {
background-color: magenta;
}
.flex-container .one,
.flex-container .four {
height: 100px;
margin: 3px;
flex-grow: 1;
flex-shrink: 0;
flex-basis: auto;
}
.flex-container .two-and-three {
order: 1;
display: flex;
flex: 0 1 100%;
flex-wrap: wrap;
}
.flex-container .two-and-three .two,
.flex-container .two-and-three .three {
background-color: #FC0;
flex: 1 0 100%;
margin: 3px;
height: 100px;
}
.flex-container .two-and-three .two {
order: 2;
}
.flex-container .two-and-three .three {
order: 1;
}
.flex-container .one {
order: 3;
}
.flex-container .four {
order: 4;
}
#media (min-width: 768px) {
.flex-container {
flex-wrap: nowrap; /* back to single row */
}
.flex-container .two-and-three {
flex-grow: 4;
flex-basis: auto; /* stop spanning the whole row */
flex-wrap: nowrap; /* back to single row */
}
.flex-container .two-and-three .two,
.flex-container .two-and-three .three {
flex-basis: 50%;
}
.flex-container .two-and-three .two {
order: 1;
}
.flex-container .two-and-three .three {
order: 2;
}
.flex-container .one {
order: 1;
}
.flex-container .four {
order: 4;
}
}
<div class="flex-container">
<div class="one">one</div>
<div class="two-and-three">
<div class="two">two</div>
<div class="three">three</div>
</div>
<div class="four">four</div>
</div>

Make HTML5 details tag to take maximum available height

I have an HTML page with header/content/footer that uses flexbox model and contains <details> tag.
I need to make details content use maximum available height, meaning that when in opened state its content should occupy all space in its container (except for summary of course).
Here is my HTML/CSS code (http://jsfiddle.net/rtojycvk/2/):
HTML:
<div class="wrapper">
<div class="header">Header</div>
<div class="main">
Some text before details
<details class="details" open>
<summary>Details summary</summary>
<div class="content">Details content</div>
</details>
</div>
<div class="footer">Footer</div>
</div>
CSS:
html, body {
height: 100%;
margin: 0; padding: 0;
}
.wrapper {
display: flex;
flex-direction: column;
width: 100%;
min-height: 100%;
}
.header {
height: 50px;
background-color: yellow;
flex: 0 0 auto;
}
.main {
background-color: cyan;
flex: 1;
display: flex;
flex-direction: column;
}
.footer {
height: 50px;
background-color: green;
flex: 0 0 auto;
}
.content {
background-color: blue;
color: white;
flex: 1;
}
.details {
background-color: red;
flex: 1;
display: flex;
flex-direction: column;
}
As you can see, the details tag itself takes all the available space, but not its content.
P.S. I need this to work only in Chrome.
http://jsfiddle.net/rtojycvk/16/
use position absolute on content, position relative on details, and calc() css (to offset the summary height)
.content {
background-color: lightgray;
color: black;
flex: 1;
display:flex;
position:absolute;
height: calc(100% - 18px);
width: 100%;
}
.details {
background-color: gray;
flex: 1;
display: flex;
flex-direction: column;
position:relative;
}
hope this helps! (I changed the colors cause they were a bit bright for me :p)
Absolute positioned .content and details relative.
fiddle
html, body {
height: 100%;
margin: 0; padding: 0;
}
.wrapper {
display: flex;
flex-direction: column;
width: 100%;
min-height: 100%;
}
.header {
height: 50px;
background-color: yellow;
flex: 0 0 auto;
}
.main {
background-color: cyan;
flex: 1;
display: flex;
flex-direction: column;
}
.footer {
height: 50px;
background-color: green;
flex: 0 0 auto;
}
.content {
background-color: blue;
color: white;
flex: 1;
position: absolute;
top: 3%;
bottom: 0;
height: 97%;
width: 100%;
}
details {
position: relative;
}
summary{
height: 3%;
}
.details {
background-color: red;
flex: 1;
display: flex;
flex-direction: column;
}
For those who prefer not to set absolutes positions, or can't do it, there is another way to accomplish it: using vh for height of .content:
html,
body {
margin: 0;
padding: 0;
height:100vh;
background: orange;
}
.wrapper {
display: flex;
flex-direction: column;
width: 100%;
height:100vh;
background: pink;
}
.header,
.footer {
height: 10vh;
min-height: 25px; /* (or max-height, or both!) */
max-height: 50px;
background-color: yellow;
flex: 0 0 auto;
}
.footer {
background-color: green;
}
.main {
background-color: cyan;
flex: 1;
display: flex;
flex-direction: column;
height: calc(100vh - 20vh); /* 10vh * 2 (.header + .footer sizes) */
}
.content {
background-color: blue;
color: white;
flex: 1;
display: flex;
flex-direction: column;
height: calc(100vh - 20vh); /* 10vh * 2 (.header + .footer sizes) */
}
.details {
background-color: red;
flex: 1;
display: flex;
flex-direction: column;
}
<div class="wrapper">
<header class="header">Header</header>
<main class="main">
Some text before details
<details class="details" open>
<summary>Details summary</summary>
<div class="content">Details content</div>
</details>
</main>
<footer class="footer">Footer</footer>
</div>
Fiddle's here: http://jsfiddle.net/ALXWebDev/wxm0v49c/
Hope it helps!