Today I'm facing a challenging situation (at least for me).
Actually I have to make some divs flexible inside a parent div and having another fixed div as a 'brother'. These flexible divs must be 100% according to the width of their parent.
Here you go a picture made to explain my situation:
I was thinking something like:
.parent {
width: 500px; /* this value can change any time */
padding: 10px;
border: 1px solid red;
float: left;
}
.parent div {
float: left;
border: 1px solid #ccc;
}
.fixed {
width: 100px;
height: 100px;
background: #ccc;
}
.flexible {
width: calc(100% - 100px); /* IT IS NOT WORKING AS I WOULD LIKE */
}
<div class='parent'>
<div class='fixed'>*fixed</div>
<div class='flexible'>*flexible 1</div>
<div class='flexible'>*flexible 2</div>
</div>
Someone could help me?
Thanks
You can use flexbox for this. You should wrap your two flexible divs in a container so that they will stack. Then you can set the parent to display: flex; flex-direction: row;. Then set your flexible wrapper to display: flex; flex-direction: column; and set flex-grow: 1 on the flexible divs and the flexible wrapper so they expand to fill both the vertical and horizontal space.
.parent {
width: 500px;
padding: 10px;
border: 1px solid red;
display: flex;
flex-direction: row;
}
.parent div {
border: 1px solid #ccc;
}
.flexcontainer {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.fixed {
width: 100px;
height: 100px;
background: #ccc;
}
.flexible {
flex-grow: 1;
}
<div class='parent'>
<div class='fixed'>*fixed</div>
<div class="flexcontainer">
<div class='flexible'>*flexible 1</div>
<div class='flexible'>*flexible 2</div>
</div>
</div>
You can use flexbox to achieve this layout.
.parent {
display: inline-flex; /* 1 */
padding: 10px;
border: 1px solid red;
}
.sub-container { /* 2 */
display: flex;
flex-direction: column;
align-items: stretch; /* 3 */
}
.flexible {
flex: 1; /* 4 */
border: 1px solid black;
}
.sub-container > div + div {
margin-top: 5px;
}
.fixed {
width: 100px;
height: 100px;
background: #ccc;
}
<div class='parent'>
<div class='fixed'>*fixed</div>
<div class='sub-container'>
<div class='flexible'>*flexible 1</div>
<div class='flexible'>*flexible 2 *flexible 2 *flexible 2</div>
</div>
</div>
Notes:
Inline-level flex container. (It adjusts to the width of its content.)
Create a sub-container for the flexible divs. Also uses flex properties.
An initial setting of a flex container is align-items: stretch. This means that flex items will automatically expand to cover the full length of the cross axis. In this case, that's the width.
Distribute the vertical space in the container evenly among the two flex items.
Taking your code as a base, you can add left and margin-left to .flexible. Also change the width as you need to calculate the padding and the container as well.
.flexible {
left: 0;
margin-left: 10px;
width: calc(100% - 120px); /* IT IS NOT WORKING AS I WOULD LIKE */
}
Related
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>
Layout: Mobile, Vertical Layout, Header (fixed height), Footer (fixed height). How to fill remaining space with img, constrained on height & width
This is a very common layout for me on iOS. Trying to understand how to do it in CSS.
Here's what I'm trying:
Using flexbox with flex-direction column
Setting height of header and footer (or can be done with flex-basis)
flex-shrink: 0 for header and footer so they don't shrink
flex-shrink: 1 on the image container so it shrinks if needed
Setting max-width and max-height to 100% on image
object-fit: scale-down so it keeps the aspect ratio of the image (this means there will be horizontal bars or vertical bars)
Issue: the image shrinks to fit the width, but should shrink even more than that to fit the available vertical space
HTML
<div class='container'>
<div class='header'>
Header
</div>
<div class='content'>
<div class='image-container'>
<img class="cat" src="https://jngnposwzs-flywheel.netdna-ssl.com/wp-content/uploads/2019/05/Transparent-OrangeWhiteCat-764x1024.png"/>
</div>
</div>
<div class='footer'>
Footer
</div>
</div>
CSS
.container {
background-color: #aaa;
height: 400px;
width: 175px;
display: flex;
flex-direction: column;
border: 2px solid blue;
}
.box {
border: 2px solid black;
display: flex;
justify-content: center;
align-items: center;
}
.box1 {
height: 100px;
flex-shrink: 0;
}
.box2 {
flex-shrink: 1;
}
.cat {
max-width: 100%;
max-height: 100%;
object-fit: scale-down;
border: 2px solid orange;
}
.box3 {
height: 100px;
flex-shrink: 0;
}
https://codepen.io/jeffrey-robert/pen/yLbNVZp
If you use object-fit, then the trick is to set to img :height:0;min-height:100%;width:100% and it should fill the flex child boxe, the child boxe will require flex-grow:1; too to fill the remaing space.
.container {
background-color: #aaa555;
height: 400px;
width: 175px;
display: flex;
flex-direction: column;
border: 2px solid blue;
}
.box {
border: 2px solid black;
display: flex;
justify-content: center;
align-items: center;
}
.box1 {
height: 100px;
flex-shrink: 0;
}
.box2 {
flex:1 1 auto;
}
.cat {
width: 100%;
height:0;
min-height:100%;
object-fit: scale-down;
border: 2px solid orange;
}
.box3 {
height: 100px;
flex-shrink:1;
}
<div class="container">
<div class="box box1">
1
</div>
<div class="box box2">
<img class="cat" src="https://jngnposwzs-flywheel.netdna-ssl.com/wp-content/uploads/2019/05/Transparent-OrangeWhiteCat-764x1024.png"/>
</div>
<div class="box box3">
3
</div>
</div>
Is it possible to do wrapping of child elements inside flexbox container but setting up height in percentages (for .wrap, .block and .mini)? Like here - http://jsfiddle.net/4cghpvyo/19/, but in % to make it responsive. Or any other idea how to make it responsive?
.wrap {
display: flex;
width: 100%;
height: 500px;
border: 1px solid #ccc;
flex-wrap: wrap;
flex-direction: column;
}
.block {
width: 30%;
height: 500px;
background-color: yellow;
}
.mini {
box-sizing: border-box;
width: 70%;
height: 125px;
background-color: orange;
border: 1px solid red;
}
Thanks!
Viewport units (vh/vw) is commonly used to give a parent a responsive but fixed height, where percent on its children will work, though can sometimes not be possible.
For height: 100% to work on the wrap, its parent need a set height (or being position absolute), and if the parent also use percent, its parent need a height, and so on, until the html element is reached, which height is set to the viewport's height.
Here showed by applying height to the html and body.
For the items it then becomes simple, and in your case, the block set to 100% and the mini to 25%, both columns will fill the parent height.
html, body {
height: 100%;
margin: 0;
}
.wrap {
display: flex;
height: 100%;
border: 1px solid #ccc;
box-sizing: border-box;
flex-wrap: wrap;
flex-direction: column;
}
.block {
width: 30%;
height: 100%;
background-color: yellow;
}
.mini {
box-sizing: border-box;
width: 70%;
height: 25%;
background-color: orange;
border: 1px solid red;
}
<div class="wrap">
<div class="block"></div>
<div class="mini"></div>
<div class="mini"></div>
<div class="mini"></div>
<div class="mini"></div>
</div>
Based on a comment, you mentioned that block might contain different sized images that should make up for the height, then with the given markup and using flex column direction, that won't be possible, as flex column items need its parent to have a fixed height, or else they won't wrap.
A simple solution to the problem would be to set the wrap's flex direction to row, add an extra element around the mini's (inner-wrap) and make it a flex column container.
.wrap {
display: flex;
border: 1px solid #ccc;
box-sizing: border-box;
}
.block {
width: 30%;
background-color: yellow;
}
.block img {
display: block;
width: 100%;
}
.inner-wrap {
width: 70%;
display: flex;
flex-direction: column;
}
.mini {
box-sizing: border-box;
height: 25%;
background-color: orange;
border: 1px solid red;
}
<div class="wrap">
<div class="block">
<img src="http://placehold.it/200x300">
</div>
<div class="inner-wrap">
<div class="block"></div>
<div class="mini"></div>
<div class="mini"></div>
<div class="mini"></div>
<div class="mini"></div>
</div>
</div>
I am trying to get my divs to cut the entire window evenly into four even squares.
I have the width and height property of each div set to 50vh while in a container with display: flex and flex-wrap: wrap.
But what is being displayed is four rectangular divs, not square divs at all.
I tried changing it to 50% but that did not help. Here is my code:
#container {
display: flex;
flex-wrap: wrap;
}
.square {
height: 50vh;
width: 50vh;
border: 1px solid black;
}
<div id="container">
<div class="square">Britt</div>
<div class="square">JOn</div>
<div class="square">Devin</div>
<div class="square">Brevin</div>
</div>
Is this what you are looking for?
html, body {
margin: 0;
}
#container {
display: flex;
flex-wrap: wrap;
}
.square {
flex-basis: 50%;
height: 50vw;
border: 1px solid black;
box-sizing: border-box;
}
<div id="container">
<div class="square">Britt</div>
<div class="square">JOn</div>
<div class="square">Devin</div>
<div class="square">Brevin</div>
</div>
I think in order to get square divs, you need to add
width: 200px;
height: 200px;
to your #container. You need to set the container as square first.
I am having difficulty displaying the following layout in flex. I have 5 boxes and I want to divide my container in two, displaying one box vertically and the other 4 vertically.
Here's my CSS:
.trades, .trade-panel {
flex: 1;
}
.layout-4-5 {
flex-direction: column;
}
.layout-4-5 > div {
width: 50%;
}
Then I set the basis of the fourth or last child to 100%.
.layout-4-5 > div:nth-child(1) {
flex-basis: 100%;
}
And here's my HTML
<div class="trades layout-4-5">
<!--trade-panel are my individual boxes --->
<div class="trade-panel">
</div>
</div>
Above print my layout horizontally. Considering My flex-direction is column and my first child or box has a 100% basis, shouldn't that print what I want? Please any help would be appreciated.
Note: Since the boxes are of equal size, the column containing the four other boxes should be longer, provided they are in the arrangement above, its ok. tq
I'm not entirely clear on your question or code. But here's a general solution:
flex-container-1 {
display: flex; /* establish flex container */
flex-direction: row; /* flex items will align horizontally */
justify-content: center; /* center flex items horizontally */
align-items: center; /* center flex items vertically */
/* for demo purposes only */
height: 250px;
width: 400px;
border: 1px solid #777;
background-color: lightgreen;
}
flex-container-1 > flex-item {
height: 90%;
flex: 0 0 45%; /* <flex-grow> <flex-shrink> <flex-basis> */
margin-right: 8px; /* a bit of space between the centered items */
border: 1px dashed #333;
background-color: yellow;
}
flex-container-2 {
height: 90%;
flex: 0 0 45%;
display: flex; /* flex item is now also flex container */
flex-direction: column; /* items will stack vertically */
justify-content: space-between; /* align items vertically */
}
flex-container-2 > flex-item {
flex: 0 0 22%;
border: 1px dashed #333;
background-color: yellow;
}
<flex-container-1><!-- main container -->
<flex-item></flex-item><!-- flex item #1 (first column) -->
<flex-container-2><!-- flex item #2 / nested flex container (second column) -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container-2><!-- close nested container -->
</flex-container-1><!-- close main container -->
jsFiddle
I struggled and struggled on this one and then serendipitously discovered a new solution to this problem right as I had decided to give up and use floats. I was finally able to get this to work without using separate DIVs for columns.
UPDATE: I have simplified my previous version of this by having the height specified on .items.
Provide non-percentage width and height to .items.
Use flex-direction: column on .items.
CSS:
.items {
display: flex;
flex-direction: column;
flex-wrap: wrap;
width: 40em;
height: 20em;
}
.item:first-child {
width: 20em;
height: 20em;
background-color: black;
}
.item:nth-child(2) {
width: 20em;
height: 5em;
background-color: pink;
}
.item:nth-child(3) {
width: 20em;
height: 5em;
background-color: blue;
}
.item:nth-child(4) {
width: 20em;
height: 5em;
background-color: yellow;
}
.item:last-child {
width: 20em;
height: 5em;
background-color: red;
}
HTML:
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div><!-- .items -->
Codepen:
https://codepen.io/anon/pen/ZXoqJJ
I have give margin and background color property so you can better understand.
<div id="wrapper">
<div id="left">
<div class="flex-harshad">
<div class = "flex-harshad2">
Harshad
</div></div>
</div>
<div id="right">
<div class="flex-harshad">
<div class="flex-item">world</div>
<div class="flex-item">by</div>
<div class="flex-item">Alan</div>
<div class="flex-item">Dong</div>
</div>
</div>
</div>
Here is css.
body,
div {
margin: 0;
border: 0 none;
padding: 0;
}
html,
body,
#wrapper,
#left,
#right {
height: 100%;
min-height: 100%;
}
#wrapper {
margin: 0 auto;
overflow: hidden;
}
#left {
float: left;
}
div.flex-harshad2{
margin : 5px;
margin-top : 25px;
min-height: 91%;
background : white ;
width : 90px;
}
div.flex-harshad{
background: red;
height : 100%;
width : 100px;
text-align: center;
display : inline-block;
background :orange ;
margin :10px;
}
div.flex-item {
background: white;
margin: 5px;
margin-top : 25%;
min-height : 20%;;
/* remove text-lign will not center text itself */
text-align: center;
}
Here is output :
flex-container-1 {
display: flex; /* establish flex container */
flex-direction: row; /* flex items will align horizontally */
justify-content: center; /* center flex items horizontally */
align-items: center; /* center flex items vertically */
/* for demo purposes only */
height: 250px;
width: 400px;
border: 1px solid #777;
background-color: lightgreen;
}
flex-container-1 > flex-item {
height: 90%;
flex: 0 0 45%; /* <flex-grow> <flex-shrink> <flex-basis> */
margin-right: 8px; /* a bit of space between the centered items */
border: 1px dashed #333;
background-color: yellow;
}
flex-container-2 {
height: 90%;
flex: 0 0 45%;
display: flex; /* flex item is now also flex container */
flex-direction: column; /* items will stack vertically */
justify-content: space-between; /* align items vertically */
}
flex-container-2 > flex-item {
flex: 0 0 22%;
border: 1px dashed #333;
background-color: yellow;
}
<flex-container-1><!-- main container -->
<flex-item></flex-item><!-- flex item #1 (first column) -->
<flex-container-2><!-- flex item #2 / nested flex container (second column) -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container-2><!-- close nested container -->
</flex-container-1><!-- close main container -->