Flex box items width basing off of parent container width - css

I have a parent container that has a max width and I want there to be 3 boxes to a line. I am using flex for this but I want the boxes to take up the full width of the parent container which I am only able to achieve by hard-coding the width of the boxes. How can I have them adapt to the width of the sections container rather than me putting a 32% width on the boxes?
HTML
<div class="account-component>
<div class="cart-products-container">
<div class="sections">
<div class="cart-product">
</div>
<div class="cart-product">
</div>
<div class="cart-product">
</div>
<div class="cart-product">
</div>
<div class="cart-product">
</div>
<div class="cart-product">
</div>
</div>
</div>
</div>
CSS
.account-component {
max-width: 1240px;
text-align: center;
margin: 0 auto;
display: flex;
margin-top: 100px;
.sections {
display: flex;
flex-wrap: wrap;
.cart-product {
width: 32%;
margin-bottom: 25px;
height: 445px;
background-color: pink;
&:nth-child(3n+2) {
margin-right: 24px;
margin-left: 24px;
}
}
}
}

To get the desired effect, you just need to change:
.cart-product {
flex: 0 0 33%;
margin-bottom: 25px;
height: 445px;
background-color: pink;
}

You can not use percentage on child element if you did not set the width (not max-with) of the parent element, because you won't have a width to depend on.
In your case, use flex to set the percentage of the child elements.
Here's a sample fiddle: https://jsfiddle.net/gadawag/0by7dm81/6/

Related

Cutting off overflowing image without overflow: hidden

I have a div with a fixed height, and inside it there is an image. This image is larger than the width and height of the containing div. I want to make the width of the image to match the width of the div, and then make the height of the image automatically generated.
HTML:
<template>
<div class="portfolio">
<div class="header">
Portfolio
</div>
<div class="projects">
<div class="project">
<img src="../assets/projects/charlotte_folke.jpg" />
</div>
</div>
<div class="overview">
</div>
</div>
</template>
SCSS:
.portfolio {
width: 100%;
height: 100%;
}
.header {
height: 10%;
display: flex;
font-size: 24px;
color: #B59762;
align-items: center;
justify-content: center;
}
.projects {
height: 80%;
display: flex;
overflow: auto;
flex-direction: column;
}
.project {
width: 100%;
height: 35%;
overflow: hidden;
img {
width: 100%;
height: auto;
}
}
The problem with this solution, is that the image element still takes up space below the containing div. I want to cut off the image completely, so it only takes up the available space specified by the containing div.
How can i achieve this?

Absolute scrollable div inside flex container without fixed height, is it possible?

How do I set a div as scrollable (absolute) without fixed height filling entire view, while inside a flex-box?
(https://imgur.com/7v5OFas)
(typo at the right section, its fixed width, the only height expected is to be fullpage everything)
https://codepen.io/anon/pen/oJyOOp?editors=1000
(if I add height to the relative parent of the red section, it works, but I cant have a fixed height. Adding 100% from html to the relative parent also works, but I can't also do that.)
currently it goes:
<div style="display:flex">
<div style="flex-grow:1">
<div style="display:flex">
<div style="width:45px...">
....
</div>
<div ...header code>
....
</div>
<div style="flex-grow:1; top:70px; position: relative">
<div style="position: absolute; top:0; left:0; right:0; bottom: 0; overflow: auto>
</div>
</div>
</div>
</div>
<div style="width:45px...">
....
</div>
</div>
It ends up filling the header height.
I would drop the idea of absolute content if its not necesarry and try something similiar to:
html, body {
min-height: 100%;
height: 100%;
margin: 0;
}
.container{
background: blue;
display: flex;
height: 100%;
flex-flow: row;
}
.sidebar{
background: red;
height: 100%;
width: 200px;
}
.contentWrapper{
display: flex;
flex-flow: column;
flex: 1;
}
.header {
background: yellow;
height: 100px;
width: 100%;
}
.content {
flex: 1;
overflow: auto;
}
.scrollableContent {
height: 3000px;
}
<div class="container">
<div class="sidebar"></div>
<div class="contentWrapper">
<div class="header"></div>
<div class="content">
<div class="scrollableContent">
</div>
</div>
</div>
</div>
Where you basically make every container a flex and the non scalable part of its content will have fix width/height and the other part get flex: 1 which is shorthand for taking rest of the space.

Fit flex parent cross-axis to items

Where the parent has display: flex; flex-direction: column, is it possible to make the parent's width expand to fit a flex item wider than the parent?
It's worth noting that the grandparent does not have display: flex nor a fixed width. It has a min-width: 100% though.
Yes, you can, and by using inline-flex instead of flex, it will grow with the child.
The reason why the flex parent won't grow along with its child when using flex is because flex work similar to a block element, and block element won't grow larger than its parent, which inline element does.
This can be seen here, where the grand parent, with or w/o min-width: 100%, won't grow with its content, but the inline-flex will. This would also be the case if the flex element would instead have inline-block.
Still, the parent's content will overflow and effect its surroundings as if it would grow with content, and make the outer scroll to show up.
Why the parent with min-width is slightly wider is because of the padding not being included in its set width, so adding box-sizing: border-box; to its rule will make them equal wide.
Stack snippet
.parent {
padding: 20px;
background: yellow;
}
.parent.with-min-width {
min-width: 100%;
}
.flex {
display: inline-flex;
flex-direction: column;
background-color: red;
padding: 20px;
}
.flex .item {
width: 800px;
padding: 20px;
background-color: blue;
}
<div class="parent">
<div class="flex">
<div class="item">
</div>
</div>
</div>
<div class="parent with-min-width">
<div class="flex">
<div class="item">
</div>
</div>
</div>
Using inline-flex on the parent instead of flex and inline-block on the grandparent should do the trick.
Example B shows the modifications. If the img is wider than the viewport the parent and the grandparent will accommodate it (shrink your window down so img is wider than the viewport then scroll right).
html,body {
width: auto;
}
.grandparent {
width: 300px;
background-color: blue;
padding: 10px;
}
.parent {
display: inline-flex;
flex-direction: column;
background-color: red;
padding: 10px;
}
.exampleB .grandparent {
min-width: 100%;
width: auto;
display: inline-block;
}
.exampleB .parent {
width: auto;
}
<section class="exampleA">
<div class="grandparent">
<div class="parent">
<div class="child">
<img src="//placehold.it/500x100"/>
</div>
</div>
</div>
</section>
<br/>
<section class="exampleB">
<div class="grandparent">
<div class="parent">
<div class="child">
<img src="//placehold.it/500x100"/>
</div>
</div>
</div>
</section>

Auto-resize image in flex item

I have the following html :
<div class="main-container">
<h1>A title</h1>
<p>Some text</p>
<div class="sub-container">
<img src="">
</div>
</div>
With the following CSS :
.main-container{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.sub-container{
flex-grow:2;
background-color: green;
}
Please note that I don't know the size of the container above "main-container". I'm using flex because I want the div in "main-container" to occupy all the remaining space at the bottom.
What I want is to have an image in "sub-container" which fits its parent's size in both directions (height and width). Right now if I add an image into "sub-container" it overflows and doesn't get scaled at all.
I know that flex only works for immediate children (i.e. "sub-container" but not the image inside). I tried to use flex on "sub-container" too, but I couldn't achieve anything satisfactory.
Is this layout you wanted?
Using flex: 1 1 0 to control the sub-container and using width: 100% could make the image to fit the container.
.main-container{
border: 3px solid green;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.sub-container{
flex-grow: 1 1 0;
background-color: green;
display: flex;
}
.sub-container img {
width: 100%;
height: 100%;
}
<div class="main-container">
<h1>A title</h1>
<p>Some text</p>
<div class="sub-container">
<img src="https://picsum.photos/1080/600">
</div>
</div>
You can use this class:
.img-fluid {
max-height:100%;
height:auto;
}
Don't forget to add .img-fluid to your img

How do you prevent an image from expanding beyond it's container?

I have an image with a height larger than that of it's container. The image is set to max-height: 100% and max-width: 100% but it continues to grow beyond it's containing element (in height - surprisingly not in width)
How do I prevent it from expanding beyond it's container while keeping it's aspect ratio?
An example is available at http://codepen.io/navarr/pen/zxZjjP, and the code at that example:
The HTML:
.row {
display: flex;
.col {
display: block;
border: 1px solid blue;
width: 50px;
height: 400px;
flex-grow: 1;
display: flex;
flex-direction: column;
text-align: center;
.link {
flex: 1 1 auto;
img {
max-height: 100%;
max-width: 100%;
}
}
h3 {
flex: 0 0 auto;
background: green;
}
}
}
<div class="row">
<div class="col">
<div class="link">
<img src="http://i.imgur.com/qG6NmU7.png" />
</div>
<h3>100 x 800 image</h3>
</div>
<div class="col">
<div class="link">
<img src="http://i.imgur.com/EjltysP.png" />
</div>
<h3>800 x 100 image</h3>
</div>
<div class="col">
<div class="link">
<img src="http://i.imgur.com/zJlunbp.jpg" />
</div>
<h3>800 x 100 image</h3>
</div>
<div class="col"></div>
</div>
The first box illustrates the problem: the image expanding beyond it's containing element.
The second and third box show this not being a problem as long as the image is wider than it is tall.
Add height: 100%; to the parent of the image :
.link {
flex: 1 1 auto;
height: 100%;
img {
max-height: 100%;
max-width: 100%;
}
}
demo
Set width and height to .link in css.
Check edited codepen http://codepen.io/anon/pen/azJGrK
CSS
.link {
flex: 1 1 auto;
width: 100%;
height: 80%;
img {
max-height: 100%;
max-width: 100%;
}
Replace the img tag with a div and set the image as the background image, and add this to the styling:
Background-size:contain;
This will allow the image to maintain its aspect ratio but fill the entire space of the div as much as possible.
You can also try background-size:cover; and see which one fits your needs better.
Remember, you need to include the height and width of the div when using background images.
Using the same mentality as found in the answer here, you can try setting this on the image parent:
height: 0;
min-height: 100%;
And on the img itself, set:
height: 100%;

Resources