This markup should produce a 30px high box that is 600px width, centered. But instead it shrinks the box so it is no width (or if there is content, it shrinks to the minimum content width). Wondering how to make this so the centered box is 600px, but is responsive at smaller window sizes.
* {
position: relative;
box-sizing: border-box;
}
html, body {
height: 100%;
overflow: hidden;
}
div {
display: flex;
}
body > div {
align-items: center;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
border: 1px solid orange;
}
body > div > div {
max-width: 600px;
border: 1px solid black;
}
body > div > div > div {
border: 1px solid blue;
background: red;
height: 30px;
}
<div>
<div>
<div></div>
</div>
</div>
Please try this. Give width:100% to body > div > div and body > div > div > div class.
* {
position: relative;
box-sizing: border-box;
}
html, body {
height: 100%;
overflow: hidden;
}
div {
display: flex;
}
body > div {
align-items: center;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
border: 1px solid orange;
}
body > div > div {
max-width: 600px;
border: 1px solid black;
width:100%;
}
body > div > div > div {
border: 1px solid blue;
background: red;
height: 30px;
width:100%;
}
<div>
<div>
<div></div>
</div>
</div>
That is the default behavior of a flex item, being as wide as its content, similar to an inline block.
The reason is its default flex-grow value, which is 0 and tells it to not fill the remaining space.
Add flex-grow: 1 to every level of flex item that should fill its parent.
* {
position: relative;
box-sizing: border-box;
}
html, body {
height: 100%;
overflow: hidden;
}
div {
display: flex;
}
body > div {
align-items: center;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
border: 1px solid orange;
}
body > div > div {
max-width: 600px;
border: 1px solid black;
flex-grow: 1; /* added */
}
body > div > div > div {
border: 1px solid blue;
background: red;
height: 30px;
flex-grow: 1; /* added */
}
<div>
<div>
<div></div>
</div>
</div>
Please allow me to simplify the code to its basic components. You have a div.container that is set as display:flex. Inside that you have a div which you want to adjust according to flex parameters. The inner div is set to grow and shrink according to its container:
flex: 1 1 auto; /* shorthand for flex-grow, flex-shrink, flex-basis */
It is also set to have a max-width:600px and centered in the page with margin-left and margin-right set to auto. I believe this construct meets your requirements.
div.container {
display: flex;
border: 1px solid orange;
}
div.container div {
flex: 1 1 auto;
border: 1px solid blue;
background: red;
height: 30px;
margin: 0 auto 0 auto;
max-width: 600px;
}
<div class="container">
<div></div>
</div>
Related
Is there a CSS way of getting the blue line (class .cover) in this snippet to have a width equal that of the .scrl_can, which exceeds the width of its container .prnt?
The width of .scrl_can changes based on user input. A width of 100% sets the width of .cover to the width of .prnt. I tried align-items: stretch; in .prnt and it is the same as width of 100%.
I realize there are other ways of getting the blue line in that position and of the desired width, but the real UI piece has some relatively positioned elements that "drop" below the container when selected; and setting overflow-x: hidden, cuts them off; so I was trying this method which almost works.
Thank you.
.flex_can {
display: flex;
flex-flow: row nowrap;
width: 600px;
}
.space {
flex: none;
width: 150px;
height: 50px;
margin-left: 10px;
background-color: rgb(200,200,200);
}
.prnt {
flex: 1 1;
border: 1px solid black;
padding: 5px;
display: flex;
flex-flow: column nowrap;
overflow-x: scroll;
}
.scrl_can {
width: 500px;
height: 50px;
border: 0.1px solid green;
white-space: nowrap;
}
.cover {
flex: none;
width: 100%;
height: 2px;
background-color: blue;
margin-bottom: 20px;
}
<div class="flex_can">
<div class="prnt">
<div class="scrl_can">Some words here to span the width of prnt to make it a scroll can.</div>
<div class="cover"></div>
</div>
<div class="space"></div>
</div>
I would use the ::after pseudo element.
.flex_can {
display: flex;
flex-flow: row nowrap;
width: 600px;
}
.space {
flex: none;
width: 150px;
height: 50px;
margin-left: 10px;
background-color: rgb(200,200,200);
}
.prnt {
flex: 1 1;
border: 1px solid black;
padding: 5px;
display: flex;
flex-flow: column nowrap;
overflow-x: scroll;
}
.scrl_can {
position: relative;
width: 500px;
height: 50px;
border: 0.1px solid green;
white-space: nowrap;
}
.scrl_can::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 2px;
background-color: blue;
margin-bottom: 20px;
}
<div class="flex_can">
<div class="prnt">
<div class="scrl_can">Some words here to span the width of prnt to make it a scroll can.</div>
<!-- <div class="cover"></div> DON'T NEED THIS ANYMORE -->
</div>
<div class="space"></div>
</div>
I'm positioning a modal div in the middle of the page with a max-height defined as a % of its container, in this case it shouldn't exceed 70% of the page height.
The contents of the div are two elements:
A fixed height header div
And a variable height content div
I want the modal to grow with the content until the max-height, then the content div should start scrolling. However whatever I do, the content seems to spill out of the modal like so:
This is my markup and styling:
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.modal {
max-height: 70%;
border: 5px dashed green;
border-radius: 5px;
}
.container {
/* I cannot remove this container */
display: flex;
flex-direction: column;
width: 600px;
}
.header {
flex: none;
background: red;
height: 100px;
}
.content {
flex: 1;
background: yellow;
overflow: auto;
}
.big-stuff {
margin: 10px;
background: orange;
height: 600px;
}
<div class="modal">
<div class="container">
<div class="header">
Header
</div>
<div class="content">
Content. Should shrink or grow to fit content but only to a max of the container height
<div class="big-stuff">
Large content
</div>
</div>
</div>
</div>
Unfortunately I can't change the markup so I'm trying to get this working just by modifying CSS. If I remove the .container div, then everything seems to work but I was hoping there was another way.
Full example available here: https://codepen.io/dyancat/pen/QWaOGpB
You can add flex to the modal, so that the content will not expand out of its parent (modal in this example):
.modal {
max-height: 70%;
border: 5px dashed green;
border-radius: 5px;
display: flex; /* Add this flex */
}
Just add display:flex in the css to the modal class.
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.modal {
max-height: 70%;
border: 5px dashed green;
border-radius: 5px;
display: flex;
}
.container {
/* I cannot remove this container */
display: flex;
flex-direction: column;
width: 600px;
}
.header {
flex: none;
background: red;
height: 100px;
}
.content {
flex: 1;
background: yellow;
overflow: auto;
}
.big-stuff {
margin: 10px;
background: orange;
height: 600px;
}
<div class="modal">
<div class="container">
<div class="header">
Header
</div>
<div class="content">
Content. Should shrink or grow to fit content but only to a max of the container height
<div class="big-stuff">
Large content
</div>
</div>
</div>
</div>
How can I vertically center rotated text using flexbox layout? I want something that looks like this:
Here's what I have so far:
html, body { height: 100%; }
body { background-color: #efefef; }
body > div {
align-content: center;
background-color: white;
border: 1px solid black;
display: flex;
height: 100%;
width: 25px;
}
body > div > div {
flex: 1;
transform: rotate(-90deg);
}
<div>
<div>
Where did I go?
</div>
</div>
Add white-space: nowrap and center horizontally and vertically using:
align-items: center;
justify-content: center;
(and you don't need the flex: 1!)
Also removed the browser margin and added in box-sizing: border-box to add the finishing touches.
See demo below:
* {
box-sizing: border-box;
}
html,
body {
height: 100%;
margin: 0;
}
body {
background-color: #efefef;
}
body > div {
background-color: white;
border: 1px solid black;
display: flex;
height: 100%;
width: 25px;
align-items: center;
white-space: nowrap;
justify-content: center;
}
body > div > div {
transform: rotate(-90deg);
}
<div>
<div>
Where did I go?
</div>
</div>
You can accomplish this by changing a couple things in your code:
Give your text a white-space: nowrap;.
Give your containing div a justify-content: center;.
In your containing div, change align-content to align-items.
html, body { height: 100%; }
body { background-color: #efefef; }
body > div {
align-items: center;
justify-content: center;
background-color: white;
border: 1px solid black;
display: flex;
height: 100%;
width: 25px;
}
body > div > div {
white-space: nowrap;
transform: rotate(-90deg);
}
<div>
<div>
Where did I go?
</div>
</div>
*Note You can also remove flex: 1; from your inner div, as it is not doing anything.
I've developed the following layout using the Flexbox CSS model:
html {
box-sizing: border-box;
overflow-y: none;
}
*,
*:before,
*:after {
margin: 0;
padding: 0;
box-sizing: inherit;
}
#all {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
background: #03a9f4;
}
#app {
width: 500px;
background: #ffffff;
border: solid 6px yellow;
}
header {
display: flex;
justify-content: center;
align-items: center;
border: solid 4px blue;
}
#header-para-container {
flex: 1;
}
#header-image-container {
flex: 0.6;
background: #888;
}
#header-image-container > img {
display: block;
width: 100%;
height: auto;
}
section {
display: flex;
flex-wrap: wrap;
border: solid 4px tomato;
}
figure {
display: flex;
justify-content: center;
align-items: center;
flex-basis: 50%;
border: solid 4px green;
}
figure > img {
max-width: 80%;
height: auto;
}
<div id="all">
<div id="app-container">
<div id="app">
<header>
<div id="header-para-container">
<p>Hello, this is CSS flexbox layout. Thank you for visiting this page.</p>
</div>
<div id="header-image-container">
<img src="http://placekitten.com/g/300/300" />
</div>
</header>
<section id="grid-images">
<figure>
<img src="http://placekitten.com/g/300/300" />
</figure>
<figure>
<img src="http://placekitten.com/g/300/300" />
</figure>
<figure>
<img src="http://placekitten.com/g/300/300" />
</figure>
<figure>
<img src="http://placekitten.com/g/300/300" />
</figure>
</section>
</div>
</div>
</div>
https://jsfiddle.net/petebere/fsLpw1vb/.
Would you know how to reduce responsively the height of the images and the main display element (in yellow frame) as the viewport height decreases?
The idea is that the element in yellow frame should be always fully visible and there should be no need for vertical scrolling.
At the moment when the viewport height drops, the height of the yellow container stays constant. This is probably because the browser wants to keep the sizes that I've applied to the container of the header image:
#header-image-container {
...
flex: 0.6;
...
}
and to the containers of the grid images:
figure {
...
flex-basis: 50%;
...
}
I've produced this graphic to show what I'm trying to achieve when the window height is reduced:
The images aren't scaling because they aren't bound by a fixed height on their immediate containers.
For example, the first image in the layout (in the header section), has neither a parent (.header-image-container) nor a grandparent (header) with a defined height. Here's the actual code:
header {
display: flex;
justify-content: center;
align-items: center;
border: solid 4px blue;
}
#header-image-container {
flex: 0.6;
background: #888;
}
With the code above, the image has no need to be responsive. There is no height confinement.
Try this instead:
header {
display: flex;
justify-content: center;
align-items: center;
border: solid 4px blue;
height: 20vh; /* NEW */
}
#header-image-container {
flex: 0.6;
background: #888;
height: 100%; /* NEW */
}
#header-image-container > img {
/* display: block; */
/* width: 100%; */
/* height: auto; */
height: 100%; /* NEW */
}
revised demo
The same concept above applies to the #grid-images section:
section {
display: flex;
flex-wrap: wrap;
border: solid 4px tomato;
height: 60vh; /* NEW */
}
figure {
display: flex;
justify-content: center;
align-items: center;
flex-basis: 50%;
border: solid 4px green;
height: 50%; /* NEW */
}
figure > img {
/* max-width: 80%; */
/* height: auto; */
height: 100%; /* NEW */
}
revised demo
Additional notes:
In your original code you're trying to make your images responsive with width: 100%; height: auto (in the header section) and max-width: 80%; height: auto (in the grid section). This set-up (using percentage widths) is more suited for horizontal screen re-sizing. Your question seeks vertical re-sizing, so use percentage heights instead.
In your original layout, you may have noticed that when you reduce the screen height, the layout disappears at the top of the screen, with no access via vertical scroll. This is a known issue with flexbox. The solution is to use margin: auto on the centered flex item, instead of justify-content: center; align-items: center on the flex container. Full details here: Can't scroll to top of flex item that is overflowing container
I have an element with 2 children.
I'm trying to have:
div grow as much as it needs based on 1 of its children
the other always fit the parents height
Thus, I want to avoid setting a height on the parent.
The problem arises when trying to handle overflow of the second child.
Here's the code:
.banner {
display: flex;
background-color: lightblue;
overflow: auto;
border: 4px solid black;
//max-height: 120px; // 1) IF I'M NOT SET THE SCROLL WON'T WORK
}
.constant {
color: white;
flex: 0 0 auto;
width: 200px;
// height: 150px; 2) DISABLED FOR NOW
border: 4px solid yellow;
background-color: olive;
border: 2px solid red;
}
.container {
display: flex;
text-align: center;
}
.main {
max-height: 100%; // 3) I SHOULD STOP MYSELF FROM GROWING MORE THAN MY PARENT
flex: 1;
overflow-y: scroll;
border: 2px solid white;
display: flex;
flex-direction: row-reverse;
align-items: flex-end;
flex-wrap: wrap;
}
.main div {
text-align: center;
width: 200px;
height: 80px;
}
.main-side {
flex: 0 0 auto;
color: white;
background-color: grey;
border: 2px solid yellow;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
background-repeat: no-repeat !important;
min-width: 0px;
min-height: 0px;
}
<div class="banner">
<div class="container">
<div class="main">
<div style="background-color:coral;">A</div>
<div style="background-color:lightgoldenrodyellow;">B</div>
<div style="background-color:khaki;">C</div>
<div style="background-color:pink;">D</div>
<div style="background-color:lightgrey;">E</div>
<div style="background-color:lightgreen;">F</div>
</div>
<div class="main-side">I've a fixed size</div>
</div>
<div class="constant">I can grow...and my parent should grow if I grow</div>
</div>
If I set a fixed height on .banner everything works out, but I would like to avoid doing so if possible.
jsfiddle
Thank you.