Ive been struggling finding the right solution to this.
say you have 6 divs all different height varying content etc.
in responsive design at a 1080p screen all 6 divs fit on one row... but when the page gets small enough it changes to 3 on each row.
problem is say the second div, is the tallest out of the 1,2,3 divs then 4 5 and 6 divs get shifted out of place
Meaning the 4th div doesnt end up in line with the first div (column wise), how would you make this happen? to ensure the content ends up in the right place no matter what.
<style>
#maincontent { width: 100%; }
.content{ width: 33%; float:left;}
</style>
<div id="maincontent">
<div class="content">a</div>
<div class="content">I have a lot more content so i'm taller</div>
<div class="content">a</div>
<div class="content">I try to float left but can't get inline with the first child</div>
<div class="content">a</div>
<div class="content">a</div>
</div>
You can use the clear property:
This property indicates which sides of an element's box(es) may not be
adjacent to an earlier floating box.
Values other than 'none' potentially introduce clearance. [...] It
is used to push the element vertically past the float.
.content:nth-child(3n + 1) {
clear: left;
}
.content {
width: 33.3%;
float: left;
}
.content:nth-child(3n + 1) {
clear: left;
}
<div id="maincontent">
<div class="content">a</div>
<div class="content">I have a lot more content so i'm taller</div>
<div class="content">a</div>
<div class="content">I try to float left but can't get inline with the first child</div>
<div class="content">a</div>
<div class="content">a</div>
</div>
Alternatively, there is the amazing flexbox:
#maincontent {
display: flex; /* Magic begins */
flex-wrap: wrap; /* Multiline */
}
.content { width: 33.3%; }
#maincontent {
display: flex; /* Magic begins */
flex-wrap: wrap; /* Multiline */
}
.content {
width: 33.3%;
}
<div id="maincontent">
<div class="content">a</div>
<div class="content">I have a lot more content so i'm taller</div>
<div class="content">a</div>
<div class="content">I try to float left but can't get inline with the first child</div>
<div class="content">a</div>
<div class="content">a</div>
</div>
Related
I have a main wrapper div that is set 100% width. Inside that i would like to have two divs, one that is fixed width and the other that fills the rest of the space. How do i float the second div to fill the rest of the space. Thanks for any help.
There are many ways to do what you're asking for:
Using CSS float property:
<div style="width: 100%; overflow: hidden;">
<div style="width: 600px; float: left;"> Left </div>
<div style="margin-left: 620px;"> Right </div>
</div>
Using CSS display property - which can be used to make divs act like a table:
<div style="width: 100%; display: table;">
<div style="display: table-row">
<div style="width: 600px; display: table-cell;"> Left </div>
<div style="display: table-cell;"> Right </div>
</div>
</div>
There are more methods, but those two are the most popular.
CSS3 introduced flexible boxes (aka. flex box) which can also achieve this behavior.
Simply define the width of the first div, and then give the second a flex-grow value of 1 which will allow it to fill the remaining width of the parent.
.container{
display: flex;
}
.fixed{
width: 200px;
}
.flex-item{
flex-grow: 1;
}
<div class="container">
<div class="fixed"></div>
<div class="flex-item"></div>
</div>
Demo:
div {
color: #fff;
font-family: Tahoma, Verdana, Segoe, sans-serif;
padding: 10px;
}
.container {
background-color:#2E4272;
display:flex;
}
.fixed {
background-color:#4F628E;
width: 200px;
}
.flex-item {
background-color:#7887AB;
flex-grow: 1;
}
<div class="container">
<div class="fixed">Fixed width</div>
<div class="flex-item">Dynamically sized content</div>
</div>
Note that flex boxes are not backwards compatible with old browsers, but is a great option for targeting modern browsers (see also Caniuse and MDN). A great comprehensive guide on how to use flex boxes is available on CSS Tricks.
I don't know much about HTML and CSS design strategies, but if you're looking for something simple and that will fit the screen automatically (as I am) I believe the most straight forward solution is to make the divs behave as words in a paragraph. Try specifying display: inline-block
<div style="display: inline-block">
Content in column A
</div>
<div style="display: inline-block">
Content in column B
</div>
You might or might not need to specify the width of the DIVs
You can use CSS grid to achieve this, this is the long-hand version for the purposes of illustration:
div.container {
display: grid;
grid-template-columns: 220px 20px auto;
grid-template-rows: auto;
}
div.left {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: row1-start
grid-row-end: 3;
background-color: Aqua;
}
div.right {
grid-column-start: 3;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end; 1;
background-color: Silver;
}
div.below {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 2;
grid-row-end; 2;
}
<div class="container">
<div class="left">Left</div>
<div class="right">Right</div>
<div class="below">Below</div>
</div>
Or the more traditional method using float and margin.
I have included a background colour in this example to help show where things are - and also what to do with content below the floated-area.
Don't put your styles inline in real life, extract them into a style sheet.
div.left {
width: 200px;
float: left;
background-color: Aqua;
}
div.right {
margin-left: 220px;
background-color: Silver;
}
div.clear {
clear: both;
}
<div class="left"> Left </div>
<div class="right"> Right </div>
<div class="clear">Below</div>
<div style="width: 200px; float: left; background-color: Aqua;"> Left </div>
<div style="margin-left: 220px; background-color: Silver;"> Right </div>
<div style="clear: both;">Below</div>
<div class="container" style="width: 100%;">
<div class="sidebar" style="width: 200px; float: left;">
Sidebar
</div>
<div class="content" style="margin-left: 202px;">
content
</div>
</div>
This will be cross browser compatible. Without the margin-left you will run into issues with content running all the way to the left if you content is longer than your sidebar.
If you're not tagetting IE6, then float the second <div> and give it a margin equal to (or maybe a little bigger than) the first <div>'s fixed width.
HTML:
<div id="main-wrapper">
<div id="fixed-width"> lorem ipsum </div>
<div id="rest-of-space"> dolor sit amet </div>
</div>
CSS:
#main-wrapper {
100%;
background:red;
}
#fixed-width {
width:100px;
float:left
}
#rest-of-space {
margin-left:101px;
/* May have to increase depending on borders and margin of the fixd width div*/
background:blue;
}
The margin accounts for the possibility that the 'rest-of-space' <div> may contain more content than the 'fixed-width' <div>.
Don't give the fixed width one a background; if you need to visibly see these as different 'columns' then use the Faux Columns trick.
Give the first div float: left; and a fixed width, and give the second div width: 100%; and float: left;. That should do the trick. If you want to place items below it you need a clear: both; on the item you want to place below it.
This question already has answers here:
CSS when inline-block elements line-break, parent wrapper does not fit new width
(2 answers)
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 4 years ago.
I have a container div that has child divs with fixed widths and wraps. What I realised is that the container's width doesn't fit tightly to the content after it wraps, usually leaving a 'ghost' space on the right. Is there a way to force it to readjust the width according to its content?
.container {
max-width: 12em;
background-color: black;
}
.child {
display: inline-block;
width: 5em;
background-color: red;
}
<div class="container">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
</div>
So in this case when the child wraps after 2 of them add up to 10em, the container instead of being 10em, it is still 12em. And if the window size forces it down to a single div wrapping, the container rather than being 5em, could be 6em, 7em, 8em, etc depending on window width.
Is there a way to get rid of the 'ghost' space and make the container fit exactly to how the child is wrapping and it's total width?
Note: I am not talking about the extra space in between each child element. I'm referring to the giant gap left in the container, which causes the container to not accurately reflect the size of its child content. I understand that I can simply count how many child can fit in 12em and change the container width to be 10em to fit 2 childs perfectly. But I want that to be flexible. Is that possible?
The extra space after each child element is a result of the display: inline-block property and is due to the literal whitespace between each div in your HTML. You may verify this by removing the linebreaks between child divs so that their open and close tags are back-to-back:
<div class="container">
<div class="child">1</div><div class="child">2</div><div class="child">3</div>/*...*/
</div>
Although this will eliminate the pesky whitespace, it comes at the expense of code clarity/readability and is surely an irritating way to write HTML.
In my experience, often the best solution to this issue is to set the parent container to display: flex:
.container {
display: flex;
flex-wrap: wrap;
max-width: 10em;
background-color: black;
}
.child {
display: inline-block;
width: 5em;
background-color: red;
}
<div class="container">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div><div class="child">5</div>
<div class="child">6</div>
</div>
In this case you will also need to provide the flex-wrap: wrap property to inform the flex container to wrap its contents. Presumably you can now update the container's max-width property to 10em to fit exactly the width of two child elements so I've taken the liberty of this change in the code snippet.
Looks like you want to render a table. So you may want to use:
<table>
<tr>
<td>Col1</td>
<td>Col2</td>
</tr>
...
</table>
In case im wrong:
You can do this with flex or grid
Helpful link Flexbox, Grid
.container {
max-width: 12em;
background-color: black;
display: flex;
}
.child {
display: block;
min-width: 5em;
background-color: red;
border: 1px dashed blue;
}
/* FLEX */
.container-flex {
/* new row if next element doesnt fit */
flex-wrap: wrap;
}
.container-flex .child {
/* makes children grow evenly after wrapping */
flex-grow: 1;
}
/* GRID */
.container-grid {
display: grid;
/* 2 auto-horizontally sized colums */
grid-template-columns: auto auto;
}
.container-grid .child {
/* noting to do here */
}
<div style='float: left; margin-right: 10px;'>
Flex<br>
<small>extend elements to 6em</small><br>
<hr>
<div class="container container-flex">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
</div>
</div>
<div style='float: left; margin-right: 10px;'>
Grid<br/>
<small>collapse container to 10em</small><br>
<hr>
<div class="container container-grid">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
</div>
</div>
You can do it like this
.container { max-width: 4.5em;background-color: black; }
.child { display: inline-block; width:cover; background-color: red; }
<!DOCTYPE html>
<html>
<head>
<title>Answer</title>
</head>
<body>
<div class="container">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
</div>
With the width set to 'cover' it covers the complete area leaving no space.In order to fix the black background (of container which is more or less acting like border), you can manually adjust it's size.
have a css float problem that i'm not sure how to fix or best way to fix and can't seem to find anything in searches. I have a variable amount of items to show inside a div, using a css float left on all the inner boxes (1, 2, and 3 in pic) but the float breaks with variable lines of text. the developer outlines show that because box 1 is larger that box 2, box 3 doesn't float flush left like box 1 which screws up the flow. how do i keep the vertical height of box 1 and box 2 but make box 3 float left where it should be? Doing a float: right; does the same thing but just pushes 3 to the left is div 2 is larger than div 1
This is just an example, there could be a variable number of rows and columns so just doing an Nth div css rule won't work. (the containing div is a variable width based on a few conditions including responsive design)
Almost like i have to have a variable buffer at the bottom of each item in a row to match the height of the tallest one. I also don't want to use a min-height as on rows where the divs are the same height will result in extra white space where there shouldn't be. How would i get the tallest element in a row if the number of columns are variable?
A possible solution is to use the empty clearing div trick but again how do I get the number of divs in a row when columns are variable? I tried to force a nth child::after thing in the example but it didn't work
.item:nth-child(2)::after {
clear: both;
}
Search didn't show anything that works so if anyone has a post that does please let me know.
also have to stick with CSS2 if at all possible due to a bunch of users using older browsers that don't use CSS3
One solution is to use display:inline-block for the figures rather than float:left.
.figure {
display: inline-block;
vertical-align: top;
margin: 2px 1em;
border:1px solid grey;
}
.figcaption {
margin:1em;
}
<div class="section">
<div class="figure">
<img src="http://placehold.it/250x250" alt="#">
<div class="figcaption">
Line 1<br/>Line 2
</div>
</div>
<div class="figure">
<img src="http://placehold.it/250x250" alt="#">
<div class="figcaption">
Line 1
</div>
</div>
<div class="figure">
<img src="http://placehold.it/250x250" alt="#">
<div class="figcaption">
Line 1<br/>Line 2
</div>
</div>
</div>
You need to clear:both the 3rd element actually in this case.
See solution below.
img {
width:50%;
float:left;
}
img:nth-child(3) {
clear: both;
}
<img src="http://via.placeholder.com/350x160">
<img src="http://via.placeholder.com/350x150">
<img src="http://via.placeholder.com/350x150">
If you got some complex example please provide jsfiddle.
that's because your <div>s are styled with "float" and 3rd div has floated to 1st, because 1st is taller than others.
Possible solutions (not including the hardcoding - it's like a deadly sin):
Give equal height to each item in a set
.float {
background-color: #f90;
float: left;
height: 100px;
line-height: 100px;
margin: 10px;
text-align: center;
width: calc(50% - 20px);
}
<div class="float">float 1</div>
<div class="float">float 2</div>
<div class="float">float 3</div>
Use different approach, such as flexbox
.wrapper {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.flex {
background-color: #f90;
height: 100px;
line-height: 100px;
margin: 10px;
text-align: center;
width: calc(50% - 20px);
}
<div class="wrapper">
<div class="flex" style="height: 120px;">flex 1</div>
<div class="flex">flex 2</div>
<div class="flex">flex 3</div>
</div>
I have this code:
.smallColumn{
float:left;
width: 300px;
display: inline;
}
.largeColumn{
width: 1700px;
}
<div class="container">
<div class="smallColumn" id="1">Small</div>
<div class="smallColumn" id="2">Small</div>
<div class="smallColumn" id="3">Small</div>
<div class="largeColumn">Large</div>
<div class="smallColumn" id="4">Small</div>
<div class="smallColumn" id="5">Small</div>
<div class="smallColumn" id="6">Small</div>
<div class="smallColumn" id="7">Small</div>
<div class="smallColumn" id="8">Small</div>
</div>
I want as many small columns in a row that fit the screen. How many, depends on the size of the screen its viewed on. The large column has to be on the row below of the small column it follows and cover the enire row. Any remaining small columns should be displayed on the rows below it. How can I achieve this?
Thanks!
Edit:
I dont seem to have explained my question very well. So an example:
The large column should be displayed on the row below the third small column, so its below it in the code.
When displayed on a normal screen there is room on the first row for another 3 elements (i numbered them just to be clear). I want columns 4,5 and 6 to ignore the large column and be displayed on the first row as well. Since columns 7 and 8 dont fit on the first row, they should be displayed in a row below the large column.
On a slighly larger screen there would be room for column 7 on the first row, so it should be displayed there as well.
Using floats to layouts cause break-layout problems if you don't understand fine how it works.
First of all, you don't need to put display:inline because floated elements are block elements automatically.
To fix your problem is defining float to large:
.largeColumn{
float:left;
width: 1700px;
}
Or the other solution, is remove floated elements and transform it to display: inline-block
If I understand your question correctly, you should also add float: left to .largeColumn. Good luck
Just add clear:both to .largeColumn (you don't have to specify width but of course you can):
.largeColumn{
clear: both;
}
From https://developer.mozilla.org/en-US/docs/Web/CSS/clear:
The clear CSS property specifies whether an element can be next to
floating elements that precede it or must be moved down (cleared)
below them.
What you want is using clear:both for the large element.
.largeColumn{clear: both;}
I would suggest running through MDN - float/clear, as floating elements can get tricky: MDN - float.
Here's a fiddle using your code.
Try flexbox.
.container {
display: flex;
flex-flow: wrap;
}
.smallColumn {
flex-basis: 300px;
}
.largeColumn {
flex-basis: 100%;
}
<div class="container">
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="largeColumn">Large</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
</div>
Thank you for the tip using flex. I managed to get my solution. Not the prettiest solution, but works
<div class="container">
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="largeColumn"><div class="contentDiv">test test</div></div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
<div class="smallColumn">Small</div>
</div>
.container {
display: flex;
flex-flow: wrap;
height: 60px;
}
.smallColumn {
flex-basis: 300px;
align-self: flex-start;
background-color: yellow;
}
.largeColumn {
flex-basis: 1px;
align-self: flex-start;
background-color: orange;
margin-top: 30px;
}
.contentDiv
{
background-color: orange;
position: absolute;
left:10px;
flex-basis: 600px;
}
I have this simple setup:
.container {
display: table;
width: 70%;
text-align: center;
}
div {
border: 1px solid #336;
}
.column {
display: table-cell;
}
<div class="container">
<div class="column">Column 1.</div>
<div class="column">Column 2 is a bit longer.</div>
<div class="column">Column 3.</div>
</div>
jsFiddle: http://jsfiddle.net/aqk1yy1d/
This table-cell behavior expands with window resize. I would like the center cell/div to be fixed to its content and not expand. Basically the sides should expand but not the inner cell, wich should be the size of its content.
I don't see how I can do this without setting a defined width somewhere, but that in not ok, because I will have different length of content in that middle cell....
Any pointers?
The trick is to set both the left and right column to take up 50% of the width of the table. The center column gets a width of 1px. If there is content larger than 1px in the center column it will force the center column to grow.
The first example only has text inside it, which will wrap at the first moment. To mitigate this add something like white-space: nowrap to keep all text on a single line or make sure that you have content with a width.
.container {
display: table;
width: 70%;
text-align: center;
margin-bottom: 10px;
}
div {
border: 1px solid #336;
}
.column {
display: table-cell;
}
.left,
.right {
width: 50%;
}
.center {
width: 1px;
}
.center-content {
white-space: nowrap;
}
<div class="container">
<div class="column left">Column 1.</div>
<div class="column center">Column 2 is a bit longer.</div>
<div class="column right">Column 3.</div>
</div>
<div class="container">
<div class="column left">Column 1.</div>
<div class="column center"><div class="center-content">Column 2 is a bit longer.</div></div>
<div class="column right">Column 3.</div>
</div>
If you can't find a better solution, you could try using javascript to set the width dynamically. Change your html to something like this:
<div class="container">
<div class="column">Column 1.</div>
<div id="column2Outer" class="column">
<div id="column2Inner" style="display: inline-block">Column 2 is a bit longer.</div>
</div>
<div class="column">Column 3.</div>
</div>
The javascript would be as follows:
$("#column2Outer").css("width", document.getElementById("column2Inner").clientWidth);
You would call this on $(document).ready() or whenever the content changes. You would of course also have to remove the border from the inner column so you can't tell it's a nested div