html layout: how to float divs vertically - html

How do I get divs to float vertically like in this picture:
Background: I have a grid of checkboxes with content sorted alphabetically and I'd like to have alphabetic order progress vertically (since horizontal order is quite hard to follow). All the divs have same size (width like picture, height = 1 line size).
Update: To clarify: The main intention is to have a table layout with a variable amount of columns based on available screen width and have the cells in column-major order. The actual number of divs is not known in advance.

CSS
.cols {
width:20%;
float:left;
}
.rows {
height:100px;
}
HTML
<div class="cols">
<div class="rows">Div 1</div>
<div class="rows">Div 2</div>
<div class="rows">Div 3</div>
</div>
<div class="cols">
<div class="rows">Div 4</div>
<div class="rows">Div 5</div>
<div class="rows">Div 6</div>
</div>
<div class="cols">
<div class="rows">Div 7</div>
</div>

If you are willing to set a fix height on the table holding the cells you could use flexbox.
Set your holding container to:
display: flex;
flex-direction: column;
flex-wrap: wrap;
And your child elements to:
flex-grow: 20%;
min-width: 200px;
See the pen: http://codepen.io/anon/pen/qIpAl

#KunJ : compatibility of grid layout is very bad... ie10 + only,
http://caniuse.com/css-grid
I think without JS you can't do the tricks, I had the same problem, in order to resolve them, I've load all elements, count them et replace in the good div

Although the following is not a complete solution, maybe others can build on it to achieve the necessary result:
FIDDLE
Markup
Divs wrapped in a container div
CSS
div
{
width: 100px;
height: 50px;
background: orange;
border: 1px solid yellow;
display:block;
}
div:nth-child(4n)
{
display:table-cell;
}
.container
{
display:table;
width: 100%;
}

Related

div Margins with display: inline-block [duplicate]

This question already has answers here:
Better way to set distance between flexbox items
(40 answers)
Closed 9 months ago.
I'm trying to manipulate divs without using float, using display: inline-block; in my css allows me to get the siblings next to each other within a container div, but with inline-block, I can't space them apart using margin-left: 20px;, margin-right :20px; ... and so on.
I'm sure there's a really simple solution, even if it doesn't involve using display: inline-block;, I just want to avoid floats and preferably avoid padding too.
you can try flex-box method to create space between two div which is inside a div (I conclude that from your question )
.parent{
border:2px solid red;
display:flex;
justify-content:space-around;
}
.parent div{
border:3px solid black;
}
<div class="parent">
<div class="child1">
child1
</div>
<div class="child2">
child2
</div>
</div>
you can also add many child div as you want , they will automatically make place in the parent container.
Here you can see below how i managed to do so without display:inline-block; and this will not break on any device unlike inline-block.
.box {
width: 200px;
height: 200px;
background: #F3F3F3;
color: #000;
display: flex;
align-items: center;
justify-content: center;
margin-left: 20px;
}
.container {
display: flex;
margin-bottom: 40px;
}
.container.two {
justify-content: space-between;
}
.container.three {
justify-content: space-evenly;
}
Margin 20px in between
<div class="container">
<div class="box">
BOX 1
</div>
<div class="box">
BOX 1
</div>
</div>
Align boxes on left and right according to width
<div class="container two">
<div class="box">
BOX 1
</div>
<div class="box">
BOX 1
</div>
</div>
Align even spacing on left and right
<div class="container three">
<div class="box">
BOX 1
</div>
<div class="box">
BOX 1
</div>
</div>

DIVs float in a non-linear way

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>

Put and align text with the first div of three (flexbox)

I'm trying to make this layout (I've made a picture to explain what i want to do):
So I've 4 divs where I'm going to put some text inside. I've used flexbox and justify content to align them center, but i want to put a text "Latest News" that is aligned with the first div (in this case Element 1).
I'm not able to think about an elegant solution to my problem, so I'm here to ask for help.
.wrapper{
display: flex;
justify-content: center;
}
.box{
height: 200px;
background-color: red;
margin: 10px;
width: 200px;
}
<p class="section-title">Latest News</p>
<div class="wrapper">
<div class="box">Element 1</div>
<div class="box">Element 2</div>
<div class="box">Element 3</div>
<div class="box">Element 4</div>
</div>
There are a few ways you can do it, and it depends how dynamic your box elements are going to be.
One simple solution that works for n boxes is to include the section title to the first box and give it position: absolute whilst adding margin-top to the wrapper to make space for the title.
https://codepen.io/anon/pen/MJpOrM
.wrapper {
display: flex;
justify-content: center;
margin-top: 40px;
}
.box {
height: 200px;
background-color: red;
margin: 10px;
width: 300px;
}
.section-title {
position: absolute;
top: 0px;
}
<div class="wrapper">
<div class="box">
<p class="section-title">Latest News</p>
Element 1
</div>
<div class="box">Element 2</div>
<div class="box">Element 3</div>
<div class="box">Element 4</div>
</div>
Considering that you have a fixed width for your boxes, the easiest solution is to make the section-title a fixed width too:
.section-title {
width: 1260px; //This is merely 300 * 4 + the margin
margin: auto;
}
https://codepen.io/anon/pen/BpWmJV

Expanding line to full width with only CSS

Maybe someone has any bright ideas how to replace my current solution to one of the problems via only CSS? I have a working JS solution, just curious if there is a CSS-only one.
A) Elements here have the same width, only the number of elements changes (can be more or less).
B) The line should expand to full width that is empty left here (the problem is here).
C) Text is dynamic (always other width).
Is it possible to set the B) element, so it would fill the width?
Yes it is possible with Flexbox, you can just set flex: 1 on lines and they will take rest of free space.
.content,
.a {
display: flex;
align-items: center;
}
.box {
width: 50px;
height: 50px;
margin: 5px;
background: red;
}
.line {
flex: 1;
border-bottom: 1px dashed black;
}
<div class="content">
<div class="a">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="line"></div>
<div class="text">Lorem ipsum.</div>
<div class="line"></div>
<div class="text">Text</div>
</div>

change proportions of 3 columned display: table / table-cell

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