I don't think this is possible in pure CSS. I have three floated elements within a wrapping container and I want the central of the three to be the width of its content and those either side to fill in the remaining gaps left and right of this element.
<style>
.wrap {
width: 50%;
height: 100px;
background: green;
}
.cont {
background: red;
float: left;
display: inline-block;
height: 100px;
}
.c1, .c3 {
background: blue;
width: auto;
}
</style>
<div class="wrap">
<div class="cont c1"> </div>
<div class="cont c2">content</div>
<div class="cont c3"> </div>
</div>
http://jsfiddle.net/6eLdboqw/1/
I realise this is trivial in Javascript but I want to know if there's a pure CSS solution.
You could accomplish this by using CSS tables, with the middle div having a width of 1% to 'auto shrink':
.wrap {
width: 400px;
height: 100px;
background: green;
display: table;
}
.cont {
background: red;
display: table-cell;
height: 100px;
}
.c1,
.c3 {
background: blue;
width: auto;
}
.c2 {
width: 1%;
}
<div class="wrap">
<div class="cont c1"> </div>
<div class="cont c2">content</div>
<div class="cont c3"> </div>
</div>
You could do so using flexbox.
Here is a demo: http://jsfiddle.net/6eLdboqw/3/
.wrap {
width: 400px;
height: 100px;
background: green;
display: flex;
}
.c1,
.c3
{
flex: 1 1 auto;
}
.c2
{
flex: 0 0 auto;
}
.cont {
background: red;
height: 100px;
}
.c1, .c3 {
background: blue;
width: auto;
}
flex is the short-hand property for: flex-grow, flex-shrink, flex-basis.
So what we do is: .c1, .c3 may grow and shrink, but .c2 may not grow or shrink.
Related
I want to make two div inside other div. But the second(green) div is passing the size of the main(black). I tried to set the height to 100%, but something happens that is going beyond the size of the main box, does anyone have any solutions?
.block {
width: 300px;
height: 200px;
background: black;
}
.box1 {
width: 200px;
height: 50px;
background: red;
vertical-align: top;
margin: auto;
}
.box2 {
width: 200px;
height: 100%;
background: green;
margin: auto
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
If you set child's height to 100% then the height of the parent will be inherited. If you are looking for an option where the 2nd box (green) fill the remaining space leftover by 1st box(red)
.block {
width: 300px;
height: 200px;
background: black;
display: flex;
flex-direction: column;
align-items: center;
}
.box1 {
width: 200px;
height: 50px;
background: red;
vertical-align: top;
}
.box2 {
flex: 1;
width: 200px;
background: green;
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
I am using Flex and there is no need to use overflow: hidden
You should add the overflow: hidden; to the main black box, just like the below snippet. This will make the overflow clipped.
.block {
width: 300px;
height: 200px;
background: black;
overflow: hidden;
}
.box1 {
width: 200px;
height: 50px;
background: red;
margin: auto;
}
.box2 {
width: 200px;
height: 100%;
background: green;
margin: auto;
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
But if you don't want to get rid of the remaining piece of the second box, you can do it with flexbox also. This will not trim the green box but instead, it will resize it to make sure the green box will remain in the parent black box.
.block {
width: 300px;
height: 200px;
background: black;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.box1 {
width: 200px;
height: 50px;
background: red;
}
.box2 {
width: 200px;
height: 100%;
background: green;
}
<div class="block">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
NOTE: In the flexbox version, you also won't need to use margin: auto; in the child boxes, because in the flexbox column direction align-items: center; will take care of child positions with the available attributes it gave to us.
I'm having trouble using float to create a specific layout. The problem are three boxes/containers that need are in order to have the first box and the third box be on the same line, while the second box is set underneath them. I can only seem to have the second box float right to third box. However I want the third box to float right, while the first box floats left. If you see the code in code pen, my goal is to have the green box in line with red box and the blue box below them. Thanks!
https://codepen.io/benjiesongsong/pen/VwZpRGN
.container {
width: 1200px;
overflow: auto;
margin: 0 auto
}
.box1 {
width: 800px;
height: 400px;
background: red;
float: left;
}
.box2 {
width: 800px;
height: 400px;
background: blue;
float: left;
}
.box3 {
width: 400px;
height: 400px;
background: green;
float: right;
}
<div class="container">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</div>
As long as you use floats, the order settings in your codepen have no effect (they would only apply to flexbox children) - you have to change the order of elements in the HTML code.
.container {
width: 1200px;
overflow: auto;
margin: 0 auto
}
.box1 {
width: 800px;
height: 400px;
background: red;
float: left;
}
.box2 {
width: 800px;
height: 400px;
background: blue;
float: left;
}
.box3 {
width: 400px;
height: 400px;
background: green;
float: right;
}
<div class="container">
<div class="box1"></div>
<div class="box3"></div>
<div class="box2"></div>
</div>
But if you use flexbox, you can do it with the order you have in your HTML, using display: flex and flex-wrap for the container and order settings for the children elements:
.container {
width: 1200px;
overflow: auto;
margin: 0 auto;
display: flex;
flex-wrap: wrap
}
.box1 {
width: 800px;
height: 400px;
background: red;
order: 1;
}
.box2 {
width: 800px;
height: 400px;
background: blue;
order: 3;
}
.box3 {
width: 400px;
height: 400px;
background: green;
order: 2;
}
<div class="container">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</div>
This question already has answers here:
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 3 years ago.
I use display: inline-block for div.left - div.right and div.red - div.yellow but none of them are in the same line. I set the width exactly. But it does not work at all.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
margin: 0 auto;
width: 800px;
}
.left, .right, .red, .yellow {
display: inline-block;
vertical-align: top;
}
.left {
width: 250px;
height: 500px;
background: gray
}
.right {
width: 550px;
height: 550px;
background: blue;
}
.red {
background: red;
width: 275px;
height: 200px;
}
.yellow {
background: yellow;
width: 275px;
height: 200px;
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
Update
If you need to keep inline-block styles, you need the .left and .right divs to add up to 800px. The thing with inline-block is that it will include white space and add it to the width. This is why the wrapping is still occurring. The following image shows the white space that is causing the wrapping.
There are many ways to remove white space and make this fit. One way is to add an HTML comment between the .left and right div, which removes all white space.
<div class="container">
<div class="left"></div><!--
--><div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
Demo
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
margin: 0 auto;
width: 800px;
}
.left, .right, .red, .yellow {
display: inline-block;
vertical-align: top;
}
.left {
width: 250px;
height: 500px;
background: gray
}
.right {
width: 550px;
height: 550px;
background: blue;
}
.red {
background: red;
width: 275px;
height: 200px;
}
.yellow {
background: yellow;
width: 275px;
height: 200px;
}
<div class="container">
<div class="left"></div><!--
--><div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
If you add display: flex to the .container, the immediate children (.left and .right) will align in the same row. The .right div is 50px taller than the .left div because of the explicit width being set (550px for .right, 500px for .left).
Also, you can remove this, as it will no longer have any effect due to the flexbox container.
.left, .right, .red, .yellow {
display: inline-block;
vertical-align: top;
}
Demo
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
margin: 0 auto;
width: 800px;
display: flex;
}
.left {
width: 250px;
height: 500px;
background: gray
}
.right {
width: 550px;
height: 550px;
background: blue;
}
.red {
background: red;
width: 275px;
height: 200px;
}
.yellow {
background: yellow;
width: 275px;
height: 200px;
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
if use display: inline-block , there will be some space between the elements. In order to overcome that u can use float property so that every element will be aligned in the same line.
If u want to go with display: inline-block property, you have to reduce the width of .red and .yellow,say for example
.red,.yellow{ width: 270px}
Consider the following HTML structure,
<div class='floated' id='div1'></div>
<div class='floated' id='div2'></div>
<div class='floated' id='div3'></div>
with the following CSS:
.floated {
width: 50%;
float: left;
}
#div1 {
height: 300px;
background-color:red;
}
#div2 {
height: 30px;
background-color: green;
}
#div3 {
height: 30px;
background-color: yellow;
}
This way, #div1 will take up a 300px tall part of the left side of the page, while #div2 and #div3 will get floated to the right side of the page. How could I set up my CSS, so #div1 and #div2 takes up a single row(of height 300px, the maximum height of the two), and #div3 will be placed right below #div1?
I am not controling the height of these divs, this is dynamic, it is possible that sometimes the first one will be only 20 pixels, and the second one will be 1000 pixels, and the other way around is also a possibility
Here's a fiddle: https://jsfiddle.net/1u55fukj/
You can use Flexbox on parent element (body in this case) and use flex-wrap: wrap. This will always make both div's in same row equal height or equal to height of taller one DEMO
body {
display: flex;
flex-wrap: wrap;
}
.floated {
flex: 0 0 50%;
}
#div1 {
height: 300px;
background-color: red;
}
#div2 {
background-color: green;
}
#div3 {
height: 30px;
background-color: yellow;
}
<div class='floated' id='div1'></div>
<div class='floated' id='div2'></div>
<div class='floated' id='div3'></div>
If there will be only 2 divs in row, then you can try to give clear:left to odd child.
.floated {
width: 50%;
float: left;
}
#div1 {
height: 300px;
background-color: red;
}
#div2 {
height: 30px;
background-color: green;
}
#div3 {
height: 30px;
background-color: yellow;
}
div.floated:nth-child(odd) {
clear: left
}
<div class='floated' id='div1'>
</div>
<div class='floated' id='div2'>
</div>
<div class='floated' id='div3'>
</div>
flexbox is your best option i think.
you could use a div container and then use display flex
.container{
height: 500px;
width: 100%;
display: flex;
flex-flow: row wrap;
justify-content: center;
}
.floated {
width: 50%;
}
#div1 {
height: 30%;
background-color:red;
}
#div2 {
height: 60%;
background-color: green;
}
#div3 {
height: 40%;
background-color: yellow;
}
<div class="container">
<div class="floated" id="div1"></div>
<div class="floated" id="div2"></div>
<div class="floated" id="div3"></div>
</div>
you can also center the 3rd div and a lot more :D. Flexbox have a good crossbrowsing support using -moz-, -webkit- etc,
how can I make all divs get on the same line and fill div#2 the space between the left floated div#1 and right floated div#3?
Maybe flex will help you, here is an JSFiddle.
HTML
<div class="parent">
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
</div>
CSS
.parent {
display: -webkit-flex;
display: flex;
}
.div1 {
width: 30px;
height: 30px;
background: #FFCC99;
}
.div3 {
width: 30px;
height: 30px;
background: #FCF305;
}
.div2 {
-webkit-flex: auto;
flex: auto;
height: 30px;
background: #CCFFCC;
}
You could use display: table for this kind of implementation (note this is not using tables for layout):
html,
body {
margin: 0;
padding: 0;
}
.wrap {
display: table;
width: 100vw;
}
.one {
display: table-cell;
height: 50px;
width: 20%;
background: red;
}
.two {
display: table-cell;
height: 50%;
width: 60%;
background: cornflowerblue;
}
.three {
display: table-cell;
background: lime;
height: 50px;
}
<div class="wrap">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
Notice how I haven't set a width on the last element, yet it's filling the rest of the space available?
Here's a dummy implementation:
<div id="l"></div>
<div id="r"></div>
<div id="c"></div>
<style>
#l {
float: left;
width:30%;
}
#r {
float: right;
width: 30%;
}
#c {
margin: 0 auto;
width: 40%;
}
</style>