I am reading about flex box property align-items and its value. One of the value that I am not able to get is 'stretch'. Below is my code snippet:
.container{
height: 100vh;
width: 100%;
display:flex;
align-items: stretch;
}
.box1{
background-color: red;
width:20vw;
height: 20vh;
}
.box2{
background-color: blue;
width:20vw;
}
.box3{
background-color: green;
width: 20vw;
height:30vh
}
<div class="container">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</div>
Here, I am expecting that all the three boxes must stretch to occupy maximum height i.e. 30vh. But, the output shows that the boxes height remains same. I have tried by specifying height of the container like 100vh or some other value or even replaced container 'height' property to 'min-height' and set its value to 100%, but nothing is working.
Please suggest me an edit in my code so that the 'stretch' value may be demonstrated.
The property is overriden by the defined height you have on each element and in any case will not make the items the same height unless it's to fill the container.
So remove the heights and make the container 30vh
In fact align-items: stretch; is the default value to it's actually unnecessary to include it in the first place.
.container {
height: 30vh;
width: 100%;
display: flex;
}
.box1 {
background-color: red;
width: 20vw;
}
.box2 {
background-color: blue;
width: 20vw;
}
.box3 {
background-color: green;
width: 20vw;
}
<div class="container">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</div>
Say we have the following set up:
.container {
background-color: red;
width: 500px;
min-height: 300px;
}
.child {
background-color: blue;
width: 500px;
height: 100%;
}
<div class="container">
<div class="child">
</div>
</div>
It's clear that the container element is rendering with a height set to 300px, but the child element has no height whatsoever, despite being set to 100%.
When the height of the container element is set to even 1px, the child element will suddenly fill the entire container with a height of 300px.
.container {
background-color: red;
width: 500px;
min-height: 300px;
height: 1px;
}
.child {
background-color: blue;
width: 500px;
height: 100%;
}
<div class="container">
<div class="child">
</div>
</div>
The container element is clearly rendering at 300px even without height being set so why does it require setting the height before the child element actually applies it's height: 100%?
Edit: To be clear, I'm not looking for a solution to having the child height take up the entire parent element, I would just like to understand why this behaves like this.
In the first case, you don't have any height defined so it's clear that the precentage height on child will fail.
From the specification:
Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.
min-height is only a boundary and the height of your element still depend on its content. If you will have one that exceed 300px the element will have more than 300px
.container {
background-color: red;
width: 500px;
min-height: 300px;
padding:10px;
}
.child {
background-color: blue;
width: 500px;
height: 400px;
animation:change 2s linear infinite alternate;
}
#keyframes change{
from {
height:100px;
}
}
<div class="container">
<div class="child">
</div>
</div>
In the second case you have specified a height so the precentage will work but the height calculation is a bit tricky since we also have min-height
The following algorithm describes how the two properties influence the used value of the 'height' property:
The tentative used height is calculated (without 'min-height' and 'max-height') following the rules under "Calculating heights and margins" above.
If this tentative height is greater than 'max-height', the rules above are applied again, but this time using the value of 'max-height' as the computed value for 'height'.
If the resulting height is smaller than 'min-height', the rules above are applied again, but this time using the value of 'min-height' as the computed value for 'height'.
In the second case, it's like you explicitely defined height:300px and percentage will consider this value. In this situation, even if the content is bigger the parent element will not grow and you will have overflow. You can even define a height equal to 0.
.container {
background-color: red;
width: 500px;
min-height: 300px;
height: 0;
padding:10px;
}
.child {
background-color: blue;
width: 500px;
height: 400px;
animation:change 2s linear infinite alternate;
}
#keyframes change{
from {
height:100px;
}
}
<div class="container">
<div class="child">
</div>
</div>
Same logic will happen with max-height but in this case the height need to be very big
.container {
background-color: red;
width: 500px;
max-height: 300px;
height: 99999px;
padding:10px;
}
.child {
background-color: blue;
width: 500px;
height: 400px;
animation:change 2s linear infinite alternate;
}
#keyframes change{
from {
height:100px;
}
}
<div class="container">
<div class="child">
</div>
</div>
If you are intrested you can transform your logic using flexbox and you will be able to do what you want without having to set an explicit height.
Relying on the default stretch alignment on the cross-axis
.container {
background-color: red;
width: 500px;
min-height: 300px;
display:flex;
}
.child {
background-color: blue;
width: 500px;
/* height: 100%;*/
}
<div class="container">
<div class="child">
</div>
</div>
Or using the flex-grow property instead of height in main axis:
.container {
background-color: red;
width: 500px;
min-height: 300px;
display:flex;
flex-direction:column;
}
.child {
background-color: blue;
width: 500px;
flex-grow:0.8; /* this is 80%, use 1 for 100% */
}
<div class="container">
<div class="child">
</div>
</div>
CSS grid can also handle this
.container {
background-color: red;
width: 500px;
min-height: 300px;
display:grid;
grid-template-rows:1fr;
}
.child {
background-color: blue;
width: 500px;
height:80%;
}
<div class="container">
<div class="child">
</div>
</div>
This question already has answers here:
Fixed position relative to parent element [duplicate]
(4 answers)
Closed 4 years ago.
Run the snippet below to see what I'm trying to achieve.
The main question is: Is that possible to achieve this without JavaScript?
.container {
display: flex;
width: 400px;
height: 2000px;
background-color: #aaa;
}
.left {
width: 150px;
background-color: lightgreen;
}
.right {
width: 100%;
background-color: lightcoral;
}
.fixed {
position: fixed;
height: 100px;
width: 100%;
background-color: skyblue;
}
<div class="container">
<div class="left">
My width can change anytime.
</div>
<div class="right">
<div class="fixed">
I'm fixed. Scroll the page to verify.<br /> I want to be the same width as my red parent.<br /> Any tips?
</div>
</div>
</div>
You can actually calculate the width it needs to have, based on the widths of the flex items.
The left item is given a width of 150px and the right item 100% (which resolves to 400px). This totals 550px, and that gets squeezed into the 400px flex container, so the actually used width for the right item is 400px *(400/550).
(Of course this is in the absense of any distorting factors such as flex-grow, which would make the whole calculation a lot more complex!)
.container {
display: flex;
width: 400px;
height: 2000px;
background-color: #aaa;
}
.left {
width: 150px;
background-color: lightgreen;
}
.right {
width: 100%;
background-color: lightcoral;
position:relative;
}
.fixed {
position: fixed;
height: 100px;
background-color: skyblue;
width:calc(400px * (400 / (400 + 150)));
}
<div class="container">
<div class="left">
My width can change anytime.
</div>
<div class="right">
<div class="fixed">
I'm fixed. Scroll the page to verify.<br > I want to be the same width as my red parent.<br > Any tips?
</div>
</div>
</div>
I've searched and tried a bunch of different things. I have a variable-height tophalf, and the bottom half should fill up the remaining space. A JSfiddle:
http://jsfiddle.net/UCJmQ/
CSS:
.top {
background-color: lightblue;
height: 300px;
}
.bottom {
background-color: green;
min-height: 100px;
overflow: hidden;
height: 100%;
}
html, body {
height: 100%;
}
HTML:
<div class="top"></div>
<div class="bottom">
</div>
What I'm seeing now is the green page taking up the entire window's height, not the remaining height. How can I make it take the remaining height instead?
http://jsfiddle.net/ph35V/
<div class="wrapper">
<div class="top">
300px
</div>
<div class="bottom">
Remaining height
</div>
</div>
html, body {
height: 100%;
width: 100%;
margin: 0;
}
.wrapper {
display: table;
height: 100%;
width: 100%;
}
.top {
display: table-row;
background: lightblue;
height: 300px;
}
.bottom {
display: table-row;
height: 100%;
background: green;
}
Could also use box-sizing: border-box or conflicting absolute positions
Is that variable-height specified in CSS or not?
From the fiddle I assume it is. If that's the case, try position: absolute with left, bottom, right set to 0 and top to upper div height:
DEMO
I'm trying to understand what appears to be unexpected behaviour to me:
I have an element with a max-height of 100% inside a container that also uses a max-height but, unexpectedly, the child overflows the parent:
.container {
background: blue;
padding: 10px;
max-height: 200px;
max-width: 200px;
}
img {
display: block;
max-height: 100%;
max-width: 100%;
}
<div class="container">
<img src="http://placekitten.com/400/500" />
</div>
This is fixed, however, if the parent is given an explicit height:
.container {
background: blue;
padding: 10px;
max-height: 200px;
max-width: 200px;
height: 200px;
}
img {
display: block;
max-height: 100%;
max-width: 100%;
}
<div class="container">
<img src="http://placekitten.com/400/500" />
</div>
Does anyone know why the child would not honour the max-height of its parent in the first example? Why is an explicit height required?
When you specify a percentage for max-height on a child, it is a percentage of the parent's actual height, not the parent's max-height, oddly enough. The same applies to max-width.
So, when you don't specify an explicit height on the parent, then there's no base height for the child's max-height to be calculated from, so max-height computes to none, allowing the child to be as tall as possible. The only other constraint acting on the child now is the max-width of its parent, and since the image itself is taller than it is wide, it overflows the container's height downwards, in order to maintain its aspect ratio while still being as large as possible overall.
When you do specify an explicit height for the parent, then the child knows it has to be at most 100% of that explicit height. That allows it to be constrained to the parent's height (while still maintaining its aspect ratio).
.container {
background: blue;
padding: 10px;
max-height: 200px;
max-width: 200px;
float: left;
margin-right: 20px;
}
.img1 {
display: block;
max-height: 100%;
max-width: 100%;
}
.img2 {
display: block;
max-height: inherit;
max-width: inherit;
}
<!-- example 1 -->
<div class="container">
<img class='img1' src="http://via.placeholder.com/350x450" />
</div>
<!-- example 2 -->
<div class="container">
<img class='img2' src="http://via.placeholder.com/350x450" />
</div>
I played around a little. On a larger image in firefox, I got a good result with using the inherit property value. Will this help you?
.container {
background: blue;
padding: 10px;
max-height: 100px;
max-width: 100px;
text-align:center;
}
img {
max-height: inherit;
max-width: inherit;
}
Instead of going with max-height: 100%/100%, an alternative approach of filling up all the space would be using position: absolute with top/bottom/left/right set to 0.
In other words, the HTML would look like the following:
<div class="flex-content">
<div class="scrollable-content-wrapper">
<div class="scrollable-content">
1, 2, 3
</div>
</div>
</div>
.flex-content {
flex-grow: 1;
position: relative;
width: 100%;
height: 100%;
}
.scrollable-content-wrapper {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: auto;
}
.scrollable-content {
/* Add styling here */
}
Try it below:
.flex-content {
flex-grow: 1;
position: relative;
width: 100%;
height: 100%;
}
.scrollable-content-wrapper {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: auto;
}
html {
height: 50%;
width: 50%;
}
body {
height: 100%;
width: 100%;
}
.parent {
height: 100%;
outline: 1px solid red;
}
<html>
<body>
<div class="parent">
<div class="flex-content">
<div class="scrollable-content-wrapper">
<div class="scrollable-content" id="scrollable">
1, 2, 3
</div>
</div>
</div>
</div>
<button onClick="scrollable.innerText += '\nSome more text'" style="margin-top: 1rem;">Add Line</button>
<p>
The red outline represents the parent. Click above to add a line until overflow occurs to see that the size of the parent is not increased.
</p>
</body>
</html>
I found a solution here:
http://www.sitepoint.com/maintain-image-aspect-ratios-responsive-web-design/
The trick is possible because it exists a relation between WIDTH and PADDING-BOTTOM of an element. So:
parent:
container {
height: 0;
padding-bottom: 66%; /* for a 4:3 container size */
}
child (remove all css related to width, i.e. width:100%):
img {
max-height: 100%;
max-width: 100%;
position: absolute;
display:block;
margin:0 auto; /* center */
left:0; /* center */
right:0; /* center */
}
You can use the property object-fit
.cover {
object-fit: cover;
width: 150px;
height: 100px;
}
Like suggested here
A full explanation of this property by Chris Mills in Dev.Opera
And an even better one in CSS-Tricks
It's supported in
Chrome 31+
Safari 7.1+
Firefox 36+
Opera 26+
Android 4.4.4+
iOS 8+
I just checked that vivaldi and chromium support it as well (no surprise here)
It's currently not supported on IE, but... who cares ? Also, iOS supports object-fit, but not object-position, but it will soon.
Here is a solution for a recently opened question marked as a duplicate of this question. The <img> tag was exceeding the max-height of the parent <div>.
Broken: Fiddle
Working: Fiddle
In this case, adding display:flex to the 2 parent <div> tags was the answer
Maybe someone else can explain the reasons behind your problem but you can solve it by specifying the height of the container and then setting the height of the image to be 100%. It is important that the width of the image appears before the height.
<html>
<head>
<style>
.container {
background: blue;
padding: 10px;
height: 100%;
max-height: 200px;
max-width: 300px;
}
.container img {
width: 100%;
height: 100%
}
</style>
</head>
<body>
<div class="container">
<img src="http://placekitten.com/400/500" />
</div>
</body>
</html>
The closest I can get to this is this example:
http://jsfiddle.net/YRFJQ/1/
or
.container {
background: blue;
border: 10px solid blue;
max-height: 200px;
max-width: 200px;
overflow:hidden;
box-sizing:border-box;
}
img {
display: block;
max-height: 100%;
max-width: 100%;
}
The main problem is that the height takes the percentage of the containers height, so it is looking for an explicitly set height in the parent container, not it's max-height.
The only way round this to some extent I can see is the fiddle above where you can hide the overflow, but then the padding still acts as visible space for the image to flow into, and so replacing with a solid border works instead (and then adding border-box to make it 200px if that's the width you need)
Not sure if this would fit with what you need it for, but the best I can seem to get to.
A good solution is to not use height on the parent and use it just on the child with View Port :
Fiddle Example: https://jsfiddle.net/voan3v13/1/
body, html {
width: 100%;
height: 100%;
}
.parent {
width: 400px;
background: green;
}
.child {
max-height: 40vh;
background: blue;
overflow-y: scroll;
}
Containers will already generally wrap their content nicely. It often doesn't work as well the other way around: children don't fill their ancestors nicely. So, set your width/height values on the inner-most element rather than the outer-most element, and let the outer elements wrap their contents.
.container {
background: blue;
padding: 10px;
}
img {
display: block;
max-height: 200px;
max-width: 200px;
}
http://jsfiddle.net/mpalpha/71Lhcb5q/
.container {
display: flex;
background: blue;
padding: 10px;
max-height: 200px;
max-width: 200px;
}
img {
object-fit: contain;
max-height: 100%;
max-width: 100%;
}
<div class="container">
<img src="http://placekitten.com/400/500" />
</div>