Smart / liquid inline spacing of divs - html

I have a container, with two containers inside of it.
<div id="container">
<div id="box1">
</div>
<div id="box2">
</div>
<div id="box3...4...">
</div>
</div>
I want the main container to span the entire width of the page. (Width: 100%;)
I want the two child containers to evenly spread and fill the horizontal space on the page.
I want to be able to add say a third or even forth child container and have them all fill from 50% 50% to ~33% ~33% ~33% to 25% 25% 25% 25% and so on...
If there a way to do this easily? Sorry if I didn't explain this well, it is my first time asking a question.

Simply use flex by specifying display:flex on the container and then flex:1 (or flex-grow:1 on the child elements like this :
.container {
display: flex;
}
.container .box {
flex: 1; /*or also `flex-grow:1` */
min-height: 100px;
border: 1px solid red;
}
<!-- container with 2 elements -->
<div class="container">
<div class="box">
</div>
<div class="box">
</div>
</div>
<!-- container with 3 elements -->
<div class="container">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
<!-- container with 4 elements -->
<div class="container">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
Refering to the documentation :
The flex-grow CSS property specifies the flex grow factor of a flex
item. It specifies what amount of space inside the flex container the
item should take up. The flex grow factor of a flex item is relative
to the size of the other children in the flex-container.
You can read more about flex property and flex-grow property

Related

Placing a div inside bootstrap column pushes content to new line

I'm having a text message wrapped in bootstrap column div and i'm trying to customize specific text in that column by wrapping it with another div but bootstrap pushes that text to a new line.
<div class="container">
<div class="row">
<div class="col">
Text1
</div>
<div class="col">Text2<div>Text3</div></div>
</div>
</div>
https://jsfiddle.net/e642tsb1/
Its because div has a default property of display: block; which makes the div appear in a new line. Use the bootstrap class d-inline-block to set its display: inline-block;
It will then appear in the same line.
.row {
background: white;
margin-top: 20px;
}
.col {
border: solid 1px red;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col">
Text1
</div>
<div class="col">Text2
<div class="d-inline-block">Text3</div>
</div>
</div>
</div>
Change your interior div to a span and it will appear on the same line:
<div class="container">
<div class="row">
<div class="col">
Text1
</div>
<div class="col">Text2 <span>Text3</span></div>
</div>
</div>
A div is a block level element by default, meaning its content will take the entire width of the page, so any child div will do the same. Here is your updated fiddle:
https://jsfiddle.net/2huy04kc/
That's true it will happen.
<div> Text2 </div> will push your <div> Text3 </div> to the next line as div are block elements.
A block-level element always starts on a new line and takes up the
full width available (stretches out to the left and right as far as it
can).
Better you use <span></span> or give a display: inline-block; property to the inner div containing Text3.
Learn different types of display in CSS here.
The div element is a block-level element. A block-level element always starts on a new line and takes up the full width available. You can use span element as an inline element. An inline element does not start on a new line and only takes up as much width as necessary.
Solution 1 : Replace div element with span element
<div class="container">
<div class="row">
<div class="col">
Text1
</div>
<div class="col">Text2<span>Text3</span></div>
</div>
</div>
Solution 2 : Styling div element to display as an inline element (not recommended).
<div class="container">
<div class="row">
<div class="col">
Text1
</div>
<div class="col">Text2<div style="display:inline">Text3</div></div>
</div>
</div>

Make absolute div take 100% height of parent

I have a div whose size depends on its content.
I want to have an absolute child which takes the whole space.
In Firefox I get the wanted result but not in Chromium.
How to fix it?
Which browser is rendering against the specification?
<div style="position:relative;float:left;">
<div style="position:absolute;display:table;left:0;top:0;height:100%;width:100%;background:red;">
<div style="display:table-cell;vertical-align:middle;">TEST</div>
</div>
<!-- this is an img in real with unknown size -->
<div style="width:200px;height:200px;background:yellow"></div>
</div>
You just need to change the display of this div to display:flex and use margin: auto to center the text:
<div style="position:relative;float:left">
<div style="position:absolute;display:flex;left:0;top:0;height:100%;width:100%;background:red;">
<div style="margin: auto">TEST</div>
</div>
<!-- this is an img in real with unknown size -->
<div style="width:200px;height:200px;background:yellow"></div>
</div>
Or with display: flex and align-items: center:
<div style="position:relative;float:left">
<div style="position:absolute;display:flex;left:0;top:0;height:100%;width:100%;background:red;align-items: center">
<div>TEST</div>
</div>
<!-- this is an img in real with unknown size -->
<div style="width:200px;height:200px;background:yellow"></div>
</div>

Why does applying uk-width-1-1 effect child divs of uk-grid but not nested divs of child?

Why is 100% width not applied in this implementation (where the class uk-width-1-1 is applied to nested div of child of grid container):
<div uk-grid>
<!-- column 01 -->
<div>
<!-- this will be a row, stacked -->
<div class="uk-width-1-1 mine">Row 01</div>
<!-- this will be a row, stacked -->
<div class="mine">Row 02</div>
</div>
</div>
However it is applied when implementing like this (where the class uk-width-1-1 is applied to child of grid container):
<div uk-grid>
<!-- column 01 -->
<div class="uk-width-1-1">
<!-- this will be a row, stacked -->
<div class="mine">Row 01</div>
<!-- this will be a row, stacked -->
<div class="mine">Row 02</div>
</div>
</div>
I can see how to achieve the effect I want, but would like to know what the logic is behind it so I can understand it better.
jsFiddle showing both implementations is here.
Edit:
I can replicate the behaviour using just flex styles - so I need to figure out why can child div be 100% and nested divs cannot?
<!-- nested div is only the width of the content -->
<div style="display:flex; flex-wrap: wrap">
<div>
<div style="width:100%; background: red">Item 1</div>
<div style="width:100%; background: red">Item 2</div>
</div>
</div>
<!-- if applied to child div, is 100% width of parent -->
<div style="display:flex; flex-wrap: wrap">
<div style="width:100%">
<div style="background: red">Item 1</div>
<div style="background: red">Item 2</div>
</div>
</div>
<!-- if not using flex at all, nested divs are 100% width of parent -->
<div>
<div>
<div style="width:100%; background: red">Item 1</div>
<div style="width:100%; background: red">Item 2</div>
</div>
</div>
Perhaps a flex item, which is any immediate child div in a flex container, by default is the width of its content, therefore nested divs, if given width: 100%, faithfully represent 100% of their immediate parent container's width and not the top level container where display: flex is defined?
Why does applying uk-width-1-1 effect child divs of uk-grid but not
nested divs of child?
Children of flex items is not part of the Flexbox. It is only children of a flex container (an element with display: flex) that is (or as you called them, immediate children), so your inner most div's is normal block level elements and will not respond to the set class uk-width-1-1, their parent will though, as in your second sample.
When it comes to Flexbox, one can, simplified, say they that the flex container behave similar to a block element and the flex item like a inline block.
This is also shown in your 1st replicated sample, where neither the flex item nor the inner most div's have a set width, so the inner most div's content will define the width of the flex item, in the same way a nested div in a div would, where the outer div is set to display: inline-block.
Here is some good resources:
https://www.w3.org/TR/css-flexbox-1/#box-model
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Updated
Note, a flex item can at the same time also be a flex container, like in below sample
<div style="display:flex; flex-wrap: wrap">
<div style="display:flex; flex-wrap: wrap; flex-grow: 1; ">
<div style="flex-basis: 100%; background: red">Item 1</div>
<div style="flex-grow: 1; background: red">Item 2</div>
</div>
</div>

CSS height 100% makes element height more than 100% [duplicate]

This question already has answers here:
Why does height 100% work when DOCTYPE is removed?
(5 answers)
Closed 5 years ago.
The following HTML is simple and does what I want. The green body stretches downward to fill the window.
<body style="margin:0">
<div style="height:100%;display:flex;flex-direction:column">
<div style="background:#d0d0ff">
This is a header
</div>
<div style="background:#d0ffd0;flex-grow:1">
This is the body.
</div>
</div>
</body>
But if I replace that body text with some flex columns, and I give them height:100% because I want them to stretch to the bottom, the newdiv actually gets a height greater than 100% of it's container and causes everything to scroll. Why doesn't 100% mean 100% here?
<body style="margin:0">
<div style="height:100%;display:flex;flex-direction:column">
<div style="background:#d0d0ff">
This is a header
</div>
<div style="background:#d0ffd0;flex-grow:1">
<!-- The new part -->
<div id='newdiv' style="display:flex;flex-direction:row; height:100%">
<div style="background:#ffd0d0"> Col 1 </div>
<div> Col 2 </div>
</div>
</div>
</div>
</body>
The reason you're getting the vertical scrollbar is because you're telling the div parent of col1 and col2 to be height: 100%. This by itself gives it the full height of the viewport.
From your code:
<div id='newdiv' style="display:flex; flex-direction:row; height:100%">
<div style="background:#ffd0d0"> Col 1 </div>
<div> Col 2 </div>
</div>
Except this div has a sibling: the header div, which is also taking up space.
So when the browser does it's height calculation, here is the result:
100% + (computed height of header div) > viewport height = vertical scrollbar
Instead of using defined heights, consider letting flexbox do the work. By default, flex items expand the full length of the container along the cross-axis.
So by simply declaring display: flex, child elements will expand to fill all available space (with no vertical scroll). But since a height rule will override this flex setting, we need to remove height: 100% from any flex items.
html, body { height: 100%; }
<body style="margin:0">
<div style="height:100%;display:flex;flex-direction:column">
<div style="background:#d0d0ff">
This is a header
</div>
<div style="background:#d0ffd0;flex-grow:1; display: flex;"><!--adjustment here-->
<div id='newdiv' style="display:flex;"><!--adjustment here-->
<div style="background:#ffd0d0; display: flex;"> Col 1 </div>
<div> Col 2 </div>
</div>
</div>
</div>
</body>
There are two adjustments to the original code.
added display: flex
removed height: 100%
Fiddle Demo
I would do it like this. demo
<body>
<header>Header</header>
<div class="body">
<aside>abc</aside>
<div class='inner'>content here</div>
</div>
</body>
In your css
html,body{
height: 100%;
}
body{
display: flex;
flex-direction: column;
}
.body{
flex-grow:1;
display: flex;
align-items: stretch;
}
.inner{
flex-grow: 1;
}
and this gives you a better html structure and maintainability
What about this? - http://codepen.io/arianalynn/pen/WragJP?editors=1010
<style>
body, html {margin:0;height:100%;width:100%;padding:0}
</style>
<body>
<div style="height:100%;display:flex;flex-direction:column">
<div style="background:#d0d0ff">
This is a header
</div>
<div style="background:#d0ffd0;flex-grow:1;display:flex;flex-direction:row; height:100%;-webkit-align-items:stretch">
<div style="background:#ffd0d0"> Col 1 </div>
<div style="background:red"> Col 2 </div>
</div>
</div>
</body>
I have updated your code try if this helps you.
set the height to
100vh https://jsfiddle.net/ok20071g/1/

Achieve table cell effect with floated divs

If I try to apply min-width, max-width to a floating div so that it expands to max-width when the right content is hidden does not work.
But, if I use table and 2 tds in it, the left td will expand to 100% if the right td is hidden.
Can I achieve this table effect with floated divs?
I don't think you can do what you are asking, but you can make it look like what you are asking.
Make it into two tds and put a max-width on a div inside the td. Would that work?
This isn't going to work with floats. Luckily we now have more tools at our disposal.
Here are two very simple methods to expand a div to 100% of the available width if a sibling horizontally to it is hidden or removed.
#1 – Using display: flex
Compatibility: Edge and all modern browsers. IE 10 and 11 support the non-standard -ms-flexbox.
The Basic Markup
<div class="container">
<div>
First Column
</div>
<div>
This second column can be hidden or not exist and the first column will take up its space
</div>
</div>
The CSS
The container div is given display: flex.
The containers children are give flex: 1 and they will be assigned equal width, can grow and can shrink.
.container {
width: 500px;
display: flex;
}
.container>div {
flex: 1;
background: #FF6961;
height: 200px;
margin-bottom: 20px;
}
.container>div:nth-child(even) {
background: #006961;
}
<div class="container">
<div>
Content
</div>
<div>
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when other divs are hidden.
</div>
<div style="display: none">
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when there is no other div.
</div>
</div>
Read this guide to flexbox
Read more about flexbox on the MDN
#2 – Using display: table
Compatibility: IE8+ and all modern browsers
The Basic Markup
<div class="container">
<div>
First Column
</div>
<div>
This second column can be hidden or not exist and the first column will take up its space
</div>
</div>
The CSS
The container is given display: table
The containers children are given display: table-cell and will act the same as cells in an HTML table. If a cell is hidden or is removed the other cell will take its space.
.container{
display: table;
width: 600px;
margin: 20px;
}
.container>div {
display: table-cell;
height: 200px;
background: #FF6961;
}
.container>div:nth-child(even) {
background: #006961;
}
<div class="container">
<div>
Content
</div>
<div>
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when other divs are hidden.
</div>
<div style="display: none">
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when there is no other div.
</div>
</div>
<div class="container">
<div>
Content takes up the remaining width if a cell has a fixed width.
</div>
<div style="width: 200px">
Content
</div>
</div>
Read more about CSS tables on the MDN