I have a random number of child div. The parent div height is known and fixed. I want the child divs' height to be the parent div's height divided by the number of child divs. (In my example there is two child divs but i can't know how many child divs there will be)
HTML
<div class="calendar-default">
<div class="calendar-plage" style="background-color: red;"> </div>
<div class="calendar-plage" style="background-color: green;"> </div>
</div>
CSS
.calendar-default{
background-color: black;
position: relative;
height: 100px;
width: 100px;
}
.calendar-plage{
height: auto; /* ??? */
}
The Fiddle explain my problem best : https://jsfiddle.net/z2anpsy7/
I managed to do it with javascript but i'd like to do it with CSS only. Is it possible ?
Ps: It's inside an AngularJS app, if you know an elegant angular way of solving my problem it's also great !
You can do this with flexbox and flex-direction: column;
.calendar-default {
background-color: black;
position: relative;
height: 100px;
display: flex;
flex-flow: column wrap;
}
.calendar-plage {
flex: 1 0 auto;
}
<h2>2 children</h2>
<div class="calendar-default">
<div class="calendar-plage" style="background-color: red;"> </div>
<div class="calendar-plage" style="background-color: green;"> </div>
</div>
<h2>3 children</h2>
<div class="calendar-default">
<div class="calendar-plage" style="background-color: red;"> </div>
<div class="calendar-plage" style="background-color: green;"> </div>
<div class="calendar-plage" style="background-color: blue;"> </div>
</div>
To spread the childs horizontally, we use display: table-cell and to spread the childs vertically, we can use display: table-row. But display: table-row needs some content in it, which I am providing through pseudo element as you can see in the below example.
Try to add more childs, they spread and fit inside the parent container automatically.
.parent {
height: 100px;
width: 100px;
display: table;
border: 1px solid black;
}
.child {
display: table-row;
width: 100px;
background-color: tomato;
}
.child:nth-child(2n) {
background-color: beige;
}
.child::after {
content:"";
}
Working Fiddle
.calendar-default{
position: relative;
height: 100px;
width: 100px;
}
.calendar-plage{
height:50%
}
<div class="calendar-default">
<div class="calendar-plage" style="background-color: red;"> </div>
<div class="calendar-plage" style="background-color: green;"> </div>
</div>
Related
I am trying to vertically align content without using flexbox because there were some problems with our use case, so I am trying to do it with table which works fine as vertically aligning goes but the problem is that the content inside doesn't fill the remaining height, is there possible to do that through CSS somehow ?
https://jsfiddle.net/s38haqm5/25/
<html>
<body>
<div class="row">
<div class="cell">
<div class="container">
Hello world
</div>
</div>
<div class="cella">
Cell2
</div>
</div>
</body>
</html>
.container {
background-color: red;
height: 100%;
}
.cell {
display: table-cell;
vertical-align: middle;
border: 1px solid black;
min-width: 100px;
max-width: 100px;
min-height: auto;
max-height: none;
}
.cella {
display: table-cell;
vertical-align: middle;
border: 1px solid black;
min-width: 100px;
max-width: 100px;
height: 30px;
max-height: none;
}
.row {
display: table
}
You need to define parent height. Now your .cell does not have any hight set, so .container doesnt have any value to calculate the 100% from.
Simply add some height to .cell, for example .cell {height: 30px;} (just like you have on .cella.)
Since .cella and .cell are same, Im assuming you might need this bit of an advice.
If you want your cells to be the same with the fact that one of them needs to be styled differently, add the same class on all of them, and then add id to the one that needs to be different and then style the id as you want. Keep in mind that the cell with class and id will have css values combined from both class and id
This worked for me just fine. Give it a try and tell me if it fulfills your wishes.
<html>
<body>
<div class="row">
<div class="cell" id="cell1">
<div class="container">
Hello world
</div>
</div>
<div class="cell" id="cell2">
Cell2
</div>
</div>
</body>
</html>
<style>
.container {
background-color: red;
position: absolute;
inset: 0; /*shorthand for top:0, left:0, bottom:0, right:0*/
height: 100%;
width: 100%;
/* for centering content within container
display:flex;
justify-content:center;
align-items:center;
*/
}
.cell {
display: table-cell;
vertical-align: middle;
position: relative;
border: 1px solid black;
height: min-content;
width: 100px;
}
.row {
display: table
}
</style>
What I have done is that I have set your .container to position absolute and parent .cell to relative, so it becomes a containing block of the .container, inset:0 makes the absolute .container strech over the whole relative .cell. parent. Hope this does the job!
This question already has answers here:
Maintain the aspect ratio of a div with CSS
(37 answers)
Closed 2 years ago.
I devide the div into two parts, and achieve with Flex Box in each part.
<!--My Trials-->
<body>
<div>
<div class="container1" style="display: flex;">
<div class="item1" style="flex:1;background-color: yellowgreen;">1</div>
<div class="item1" style="flex:1;background-color: lightseagreen;">2</div>
<div class="item1" style="flex:1;background-color: palevioletred">3</div>
</div>
<div class="container2" style="display: flex;">
<div class="item2" style="flex:1;background-color: lightskyblue;">4</div>
<div class="item2" style="flex:2;visibility: hidden;">5</div><!-- hide the 5th div -->
</div>
</div>
</body>
I wonder how to turn each div into a square.
And Is there anyway can achive the layout without the help of the 5th div?
.container {
display: flex;
flex-wrap: wrap;
}
.item1 {
height: 100px;
width: 33%;
background-color: lightblue;
color: black;
}
.item2 {
height: 100px;
width: 33%;
background-color: lawngreen;
color: black;
}
.item3 {
height: 100px;
width: 33%;
background-color: pink;
color: black;
}
.item4 {
height: 100px;
width: 33%;
background-color: orange;
color: black;
}
<body>
<div class="container">
<div class="item1">This is square 1</div>
<div class="item2">This is square 2</div>
<div class="item3">This is square 3</div>
<div class="item4">This is square 4</div>
</div>
</body>
The flex-wrap property allows elements to move to the next row when there is no more space on the current row. Making it completely responsive. And the width property is set to take up 33% of the view port window at all times.
Let me know if that works or if you need help with anything.
In CSS, if a child of a child is set to width: 100% and the wrapping div has display: flex set, the content does not expand to 100% it only uses the space of the content.
How would one make it expand to the size the grandchild sets itself but still use flex?
flex-grow is probably not the answer since this will always expand to take up the full space and not respect the size the grandchild sets itself.
See following example:
.wrapperFlex, .wrapperBlock{
border: 1px solid silver;
}
.wrapperFlex {
display: flex;
}
.levelOne {
}
.levelOneGrow {
flex-grow: 1;
}
.levelTwo, .levelTwoFullWidth {
color: white;
background-color: blue;
}
.levelTwoFullWidth {
width: 100%;
}
.levelOnePassthrough{
display: contents;
}
<!-- Premise -->
<div class="wrapperFlex">
<div>PRE</div>
<div class="levelOne">
<div class="levelTwoFullWidth">
WRAPPER FLEX
</div>
</div>
<div>AFTER</div>
</div>
<br/>
<!-- Not what is wanted, the grandchild here does not actually expand to 100%
it should be only as wide as the content here -->
<div class="wrapperFlex">
<div>PRE</div>
<div class="levelOneGrow">
<div class="levelTwo">
WRAPPER FLEX GROW
</div>
</div>
<div>AFTER</div>
</div>
<br/>
<!-- What is wanted but not possible, display: contents is not commonly available -->
<div class="wrapperFlex">
<div>PRE</div>
<div class="levelOnePassthrough">
<div class="levelTwoFullWidth ">
WRAPPER FLEX PASSTHROUGH
</div>
</div>
<div>AFTER</div>
</div>
Can you set flex-basis to the child?
.wrapperFlex, .wrapperBlock{
border: 1px solid silver;
}
.wrapperFlex {
display: flex;
}
.wrapperBlock {
display: block;
}
.levelOne {
flex-basis: 100%; /* Set flex-basis to 100% */
}
.levelTwo {
color: white;
width: 100%;
background-color: blue;
}
<div class="wrapperFlex">
<div class="levelOne">
<div class="levelTwo">
WRAPPER FLEX
</div>
</div>
</div>
<br/>
<div class="wrapperBlock">
<div class="levelOne">
<div class="levelTwo">
WRAPPER BLOCK
</div>
</div>
</div>
set .levelOne {width:100%} ,if im not misunderstanding you.
You need to add the flex property as one to the child i.e levelOne like this flex:1;.
It will work properly as you check here.
.wrapperFlex, .wrapperBlock{
border: 1px solid silver;
}
.wrapperFlex {
display: flex;
}
.wrapperBlock {
display: block;
}
.levelOne {
flex:1;
}
.levelTwo {
color: white;
width: 100%;
background-color: blue;
}
<div class="wrapperFlex">
<div class="levelOne">
<div class="levelTwo">
WRAPPER FLEX
</div>
</div>
</div>
<br/>
<div class="wrapperBlock">
<div class="levelOne">
<div class="levelTwo">
WRAPPER BLOCK
</div>
</div>
</div>
I have 3 columns
.bookingTotals.middleRow {
height: 315px;
bottom: 400px;
}
.bookingTotals.row {
height: 400px;
bottom: 0;
margin-left: 920px;
/*margin-right: 55px;*/
}
<div id "myParent">
<div style="float: left; width: 400px;">
//some stuff
<div>
<div style="float: left; width: 400px;">
//some stuff
<div>
<div style="float: left; width: 400px;">
<div style="height:50px;">
//top stuff
</div>
<div class="bookingTotals middleRow">
//middle stiff that fills the gap
</div>
<div class="bookingTotals row">
//bottom stuff that i want fixed to the bottom
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I want to split the last column into 3 layers where the top and bottom div heights are known. So I want the middle div to fill the space between.
What actually happens is that this footer div is displayed outside myParent as if it had no relation to it. What am I doing wrong?
I took some liberty with your height so it would show better.
Use CSS for everything, not put in the markup. Use classes for that.
I make the assumption you want the text in the last one at the bottom so I added a span around it and used align-self: flex-end; at the flex end for the row.
Background color added for clarity of the solution.
#myParent {
width: 100px;
}
.rowthing {
width: 410px;
}
.holder {
display: flex;
flex-direction: column;
min-height: 350px;
border: solid 1px red;
}
.things {
display: flex;
}
.topstuff {
height: 50px;
background-color: #ddeeee;
}
.bookingTotals.middleRow {
flex-grow: 1;
background-color: #dddddd;
justify-content: space-evenly;
}
.bookingTotals.middleRow span {
align-self: center;
}
.bookingTotals.bottom {
height: 100px;
background-color: #eeeedd;
justify-content: center;
}
.bookingTotals.bottom span {
align-self: flex-end;
}
<div id "myParent">
<div class="rowthing">
//some stuff1
</div>
<div class="rowthing">
//some stuff2
</div>
<div class="rowthing holder">
<div class="things topstuff">
//top stuff
</div>
<div class="things bookingTotals middleRow">
<span> //middle stiff that fills the gap<span>
</div>
<div class="things bookingTotals bottom">
<span>bottom stuff that i want fixed to the bottom<span>
</div>
</div>
</div>
If you use the bottom property you also need to specify position.
I used calc to fill the space. In this way, the height of the middle row will depend on the screen size.
.top-row {
height: 50px;
background: red;
}
.bookingTotals.middleRow {
height: calc(100vh - 400px);
background: orange;
}
.bookingTotals.row {
height: 290px;
background: yellow;
}
<div id="myParent">
<div>
some stuff
<div>
<div style="width: 400px;">
some stuff
<div>
<div style="width: 400px;">
<div class="top-row">
top stuff
</div>
<div class="bookingTotals middleRow">
middle stiff that fills the gap
</div>
<div class="bookingTotals row">
bottom stuff that i want fixed to the bottom
<div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I have two instances of the same row-component that has display: flex and justify-content: space-between:
<div class="component-row">
<div>looooooooooong</div>
<div>short</div>
<div>mediummm</div>
</div>
<div class="component-row">
<div>looooooooooong</div>
<div>short</div>
<div>mediummm</div>
</div>
The spacing between the children of each component will be different because the children have different widths. Without changing the order of the children, how can I make sure that both component instances have the same amount of space between each of their children? Within the instance, the space (ex. the space between long and short) doesn't have to be equal - what I want is the space between the 1st and 2nd child of both instances to be the same, and the space between the 2nd and 3rd child of both instances to be the same.
It sounds really easy solution but it is, just give a fixed width on a class and then place it on the .component-row childrens.
.component-row {
display: flex;
justify-content: space-between;
}
.eq1 {
width: 30%;
}
.eq2 {
width: 20%;
}
.eq3 {
width: 35%;
}
<div class="component-row">
<div class="eq1" style="background-color: red;">looooooooooong</div>
<div class="eq2" style="background-color: purple;">short</div>
<div class="eq3" style="background-color: pink;">awdasdsdasad</div>
</div>
<div class="component-row">
<div class="eq1" style="background-color: green;">looooooooooong</div>
<div class="eq2" style="background-color: yellow;">srt</div>
<div class="eq3" style="background-color: blue;">mediummm</div>
</div>
The most obvious would be to give each item a width, though if you can't or don't want, flexbox is not the best solution, a grid is.
As CSS Grid lacks good browser support, CSS Table doesn't, and is the perfect choice to accomplish this task.
.component-container {
display: table;
width: calc(100% - 40px);
}
.component-row {
display: table-row;
}
.component-row div {
position: relative;
display: table-cell;
border: 1px solid gray;
}
.component-row div:nth-child(2) {
left: 20px;
}
.component-row div:nth-child(3) {
left: 40px;
}
<div class="component-container">
<div class="component-row">
<div>looooooooooong</div>
<div>mediummm</div>
<div>short</div>
</div>
<div class="component-row">
<div>short</div>
<div>looooooooooong</div>
<div>mediummm</div>
</div>
</div>