Horizontally align elements with different height - css

I'm building a web page where the search results should appear horizontally aligned. The elements could have different heights.
The examples I'd like to reproduce are:
Google Plus posts layout
Isotope (http://isotope.metafizzy.co).
I tried to use floating elements but you can see my failure in this Plunkr
http://plnkr.co/8ex35N8OraWZBnbE5EoY

Option #1 : nth-child
If you have a fixed number of columns, you can use :
/* Style */
.item { background: yellow; width: 48px; border: 1px solid black; }
.item:nth-child(2n) { background: blue; }
.item:nth-child(3n) { background: red; }
/* Position */
.container {
width: 200px;
}
.item {
float: left;
}
.item:nth-child(4n+1) {
clear: left;
}
<div class="container">
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo<br>fred<br>plugh<br>xyzzy<br>thud</div>
<div class="item">foo<br>bar<br>baz<br>qux</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo<br>fred<br>plugh<br>xyzzy<br>thud</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo</div>
<div class="item">foo<br>bar<br>baz</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault</div>
<div class="item">foo</div>
<div class="item">foo<br>bar<br>baz</div>
</div>
Option #2 : clearfix
Under IE9, you can use a clearfix :
/* Style */
.item { background: yellow; width: 48px; border: 1px solid black; }
.item:nth-child(2n) { background: blue; }
.item:nth-child(3n) { background: red; }
/* Position */
.container {
width: 200px;
}
.item {
float: left;
}
.clear {
clear: both;
height: 0px;
}
<div class="container">
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo<br>fred<br>plugh<br>xyzzy<br>thud</div>
<div class="item">foo<br>bar<br>baz<br>qux</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo<br>fred<br>plugh<br>xyzzy<br>thud</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo</div>
<p class="clear"> </p>
<div class="item">foo<br>bar<br>baz</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault</div>
<div class="item">foo</div>
<div class="item">foo<br>bar<br>baz</div>
</div>
Options #3 : rows
Another way to do it under IE9 : add rows.
/* Style */
.item { background: yellow; width: 48px; border: 1px solid black; }
.item:nth-child(2n) { background: blue; }
.item:nth-child(3n) { background: red; }
/* Position */
.container {
width: 200px;
}
.item {
float: left;
}
.row {
clear: both;
}
<div class="container">
<div class="row">
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo<br>fred<br>plugh<br>xyzzy<br>thud</div>
<div class="item">foo<br>bar<br>baz<br>qux</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo<br>fred<br>plugh<br>xyzzy<br>thud</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo</div>
</div>
<div class="row">
<div class="item">foo<br>bar<br>baz</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault</div>
<div class="item">foo</div>
<div class="item">foo<br>bar<br>baz</div>
</div>
</div>
Option #4 : columns
This option requires to rearrange items order.
/* Style */
.item { background: yellow; width: 48px; border: 1px solid black; }
.item:nth-child(2n) { background: blue; }
.item:nth-child(3n) { background: red; }
/* Position */
.container {
width: 200px;
}
.column {
width: 50px;
float: left;
}
<div class="container">
<div class="column">
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge</div>
<div class="item">foo<br>bar</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply</div>
</div>
<div class="column">
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo<br>fred<br>plugh<br>xyzzy<br>thud</div>
<div class="item">foo<br>bar</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge</div>
</div>
<div class="column">
<div class="item">foo<br>bar<br>baz<br>qux<br>quux</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo<br>fred</div>
<div class="item">foo<br>bar<br>baz<br>qux</div>
</div>
<div class="column">
<div class="item">foo<br>bar<br>baz</div>
<div class="item">foo<br>bar<br>baz</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge</div>
</div>
</div>
Option #5 : Masonry
Finally, a JS solution with Masonry :
var container = document.querySelector('.container');
var msnry = new Masonry( container, {
// options
columnWidth: 50,
itemSelector: '.item'
});
/* Style */
.item { background: yellow; width: 48px; border: 1px solid black; }
.item:nth-child(2n) { background: blue; }
.item:nth-child(3n) { background: red; }
/* Position */
.container {
width: 200px;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/masonry/3.1.2/masonry.pkgd.js"></script>
<div class="container">
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge</div>
<div class="item">foo<br>bar</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo<br>fred<br>plugh<br>xyzzy<br>thud</div>
<div class="item">foo<br>bar</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge<br>grault<br>garply<br>waldo<br>fred</div>
<div class="item">foo<br>bar<br>baz<br>qux</div>
<div class="item">foo<br>bar<br>baz</div>
<div class="item">foo<br>bar<br>baz</div>
<div class="item">foo<br>bar<br>baz<br>qux<br>quux<br>corge</div>
</div>

Related

Grid layout with auto columns resize with a full-width flex child

I have created a table with expandable rows using CSS Grid Layout and everything works fine until I add an element with a flex layout in the expandable section.
The expandable section use a grid-column: 1/-1; and the content should not affect the rest of the grid or that is what i thought.
I have created a simplified version to show the problem:
function toggle() {
const elem = document.querySelector('.all-columns');
if (elem.style.display === "none") {
elem.style.display = "flex";
} else {
elem.style.display = "none";
}
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
width: 400px;
}
.row {
display: contents;
}
.all-columns {
grid-column: 1/-1;
display: flex;
flex-wrap: wrap;
background: red;
border: 1px solid black;
}
.column {
border: 1px solid black;
}
.flex-child {
width: 180px;
text-align: center;
background: blue;
border: 1px solid black;
}
<div class="grid-container">
<div class="row">
<div class="column">Row1 Column1</div>
<div class="column">Row1 Column2 with large name</div>
<div class="column">Row1 Column3</div>
</div>
<div class="row">
<div class="all-columns">
<div class="flex-child">1 flex</div>
<div class="flex-child">2 flex</div>
<div class="flex-child">3 flex</div>
<div class="flex-child">4 flex</div>
<div class="flex-child">5 flex</div>
</div>
</div>
<div class="row">
<div class="column">Row3 Column1</div>
<div class="column">Row4 Column2</div>
<div class="column">Row1 Column3</div>
</div>
</div>
<br>
<button onclick="toggle()">Toggle expandable section</button>
As you can see, the size of the middle column changes when the expandable section is shown/hide.
The content of the expandable section is external so I cannot modify it at all.
I have tested it in Firefox and Chrome with the same result.
I'd appreciate if someone has an explanation for this behaviour.
Thanks.
add width: 0;min-width: 100%; to all-columns so it won't contribute to defining the width and won't affect the other elements:
function toggle() {
const elem = document.querySelector('.all-columns');
if (elem.style.display === "none") {
elem.style.display = "flex";
} else {
elem.style.display = "none";
}
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
width: 400px;
}
.row {
display: contents;
}
.all-columns {
grid-column: 1/-1;
width: 0;
min-width: 100%;
display: flex;
flex-wrap: wrap;
background: red;
border: 1px solid black;
}
.column {
border: 1px solid black;
}
.flex-child {
width: 180px;
text-align: center;
background: blue;
border: 1px solid black;
}
<div class="grid-container">
<div class="row">
<div class="column">Row1 Column1</div>
<div class="column">Row1 Column2 with large name</div>
<div class="column">Row1 Column3</div>
</div>
<div class="row">
<div class="all-columns">
<div class="flex-child">1 flex</div>
<div class="flex-child">2 flex</div>
<div class="flex-child">3 flex</div>
<div class="flex-child">4 flex</div>
<div class="flex-child">5 flex</div>
</div>
</div>
<div class="row">
<div class="column">Row3 Column1</div>
<div class="column">Row4 Column2</div>
<div class="column">Row1 Column3</div>
</div>
</div>
<br>
<button onclick="toggle()">Toggle expandable section</button>

Select child elements under 2 levels from the parent div

Am currently having a code something like below to render 9 boxes like a rubix cube
#child {
height: 30px;
width: 30px;
float: left;
margin: 1px;
background-color: rgba(235, 26, 224, 0.829);
}
#outer {
position: absolute;
}
<div id="outer">
<div id="inner">
<div id="child"></div>
<div id="child"></div>
<div id="child"></div>
</div>
<div>
<div id="child"></div>
<div id="child"></div>
<div id="child"></div>
</div>
<div>
<div id="child"></div>
<div id="child"></div>
<div id="child"></div>
</div>
</div>
Am trying to assign different colors to the 9 divs using nth-child, but the browser is considering the divs as 3 different elements and not 9, as there is an intermediate div #inner which is another parent of the #child
#child:nth-child(2) {
background-color: blue;
}
#child:nth-child(3) {
background-color: green;
}
#child:nth-child(4) {
background-color: red;
}
#child:nth-child(5) {
background-color: yellow;
}
#child:nth-child(6) {
background-color: black;
}
/* and so on for 9 divs */
Can someone help me on this to differentiate the #child divs only with CSS
You'll have to select the parent before selecting the children:
.inner div {
display: inline-block;
width: 100px;
height: 100px;
}
/* The first inner element, first child */
.inner:nth-child(1) :nth-child(1) {
background: black;
}
/* The first inner element, second child */
.inner:nth-child(1) :nth-child(2) {
background: red;
}
/* The first inner element, third child etc.. */
.inner:nth-child(1) :nth-child(3) {
background: blue;
}
.inner:nth-child(2) :nth-child(1) {
background: green;
}
.inner:nth-child(2) :nth-child(2) {
background: orange;
}
.inner:nth-child(2) :nth-child(3) {
background: yellow;
}
.inner:nth-child(3) :nth-child(1) {
background: pink;
}
.inner:nth-child(3) :nth-child(2) {
background: purple;
}
.inner:nth-child(3) :nth-child(3) {
background: brown;
}
<div id="outer">
<div class="inner">
<div></div>
<div></div>
<div></div>
</div>
<div class="inner">
<div></div>
<div></div>
<div></div>
</div>
<div class="inner">
<div></div>
<div></div>
<div></div>
</div>
</div>
Just give each child an ID and use it to assign colours
HTML IS:
<div id="outer">
<div>
<div id="child1">1</div>
<div id="child2">2</div>
<div id="child3">3</div>
</div>
<div>
<div id="child4">4</div>
<div id="child5">5</div>
<div id="child6">6</div>
</div>
<div>
<div id="child7">7</div>
<div id="child8">8</div>
<div id="child9">9</div>
</div>
</div>
CSS is:
#child1{
background-color: red;
color:red;
}
#child2{
background-color: blue;
}
#child3{
background-color: green;
}
#child4{
background-color: pink;
}
#child5{
background-color: yellow;
}
#child6{
background-color: white;
}
#child7{
background-color: black;
}
#child8{
background-color: orange;
}
#child9{
background-color: red;
}

How to repeat display grid area for n element

I need repeat this multiple rows code pen issue
<div class="list-view">
<div class="card">lorem</div>
<div class="card">ipsum</div>
<div class="card">dolor</div>
<div class="card">sit</div>
<div class="card">lorem</div>
<div class="card baner">banner</div>
</div>
.list-view {
display: grid;
border: 1px solid red;
grid-template-areas: "list advertisment";
grid-template-columns: auto 240px;
.card {
background: #ccc;
border:1px solid green;
grid-area: list;
height: 100px;
&.baner {
grid-area: advertisment;
background: yellow;
}
}
}
You can assign the grid items to a specific grid-column, instead of grid-area.
codepen
.list-view {
display: grid;
border: 1px solid red;
grid-template-columns: auto 240px;
}
.card {
background: #ccc;
border: 1px solid green;
height: 100px;
grid-column: 1;
}
.baner {
background: yellow;
grid-column: 2;
}
<div class="list-view">
<div class="card">lorem</div>
<div class="card">ipsum</div>
<div class="card">dolor</div>
<div class="card">sit</div>
<div class="card">lorem</div>
<div class="card baner">banner</div>
<div class="card">lorem</div>
<div class="card">ipsum</div>
<div class="card">dolor</div>
<div class="card">sit</div>
<div class="card">lorem</div>
<div class="card baner">banner</div>
<div class="card">lorem</div>
<div class="card">ipsum</div>
<div class="card">dolor</div>
<div class="card">sit</div>
<div class="card">lorem</div>
<div class="card baner">banner</div>
</div>

CSS How do I force a container to be displayed underneath a preceding container whose elements float left

I want the div which displays "D" to appear beneath that one which displays "A" so that divs with matching background colours appear stacked over one another. However, I am getting this:
Where exactly in my CSS code must I clear my float?
#container {
background-color: #333333;
width: 990px;
}
#left {
background-color: red;
width: 300px;
float: left;
}
#splitter {
background-color: green;
width: 90px;
float: left;
}
#right {
background-color: blue;
width: 200px;
float: left;
}
<div id="container">
<div id="left">A</div>
<div id="splitter">B</div>
<div id="right">C</div>
</div>
<div id="container">
<div id="left">D</div>
<div id="splitter">E</div>
<div id="right">F</div>
</div>
You have to deal with floats and for this you need to understand what floats and BFC are :
a few ways to do this, that you should understand once you been reading a bit about floats, clearing and Block formating context.
(last example in the snippet below, oldish, even avoids the floats but does the layout)
/* DEMO purpose : Show the id or class being used on that container*/
section:before {
content: attr(id)' 'attr(class);
display: table;
background: #177EE5;
padding: 5px;
margin: 5px;
color: #fff;
text-shadow: 0 0 1px black, 0 0 1px black, 0 0 1px black, 0 0 1px black, 0 0 1px black, 0 0 1px black;
letter-spacing: 1px;
font-variant: small-caps;
}
/* your css turned into class to be valid since used for many tags */
.container {
background-color: #333333;
width: 990px;
}
.left {
background-color: red;
width: 300px;
float: left;
}
.splitter {
background-color: green;
width: 90px;
float: left;
}
.right {
background-color: blue;
width: 200px;
float: left;
}
/* wrapper for each examples */
section {
clear: both;
overflow: hidden;
margin: 1em;
}
/* different ways shown, usefull for testing only if you read about floats and dig a bit */
/* table */
.table .container {
display: table;
}
/* overflow */
.overflow .container {
overflow: hidden;
}
/* float */
.float .container {
float: left;
}
/* flex */
.flex .container {
display: flex;
}
/* inline-block */
.inline-block .container {
display: inline-block;
vertical-align: top;
}
/* last examples without floats */
/*no float & ie8 */
#table div {
float: none
}
#table #first-row,
#table > div {
display: table-row;
}
#table > div > div {
display: table-cell;
}
#table {
background-color: #333333;
width: 990px;
table-layout: fixed;
}
#left {
width: 300px;
}
#splitter {
width: 90px;
}
#right {
width: 200px;
}
#table > div > div {
background-color: red;
}
#table > div > div + div {
background-color: green;
}
#table > div > div + div + div {
background-color: blue;
}
#table:before {
display: table-caption;
width: 100%;
margin: 0;
}
#table > div:after {
content: "Notice there's a gap to fill here since cols do not cover the 990px";
display: table-cell;
}
<section class="your CSS :-: no BFC involved">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<section class="table">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<section class="overflow">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<section class="float">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<section class="flex">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<section class="inline-block">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<p>another way without float including IE8 ?</p>
<section id="table" class="table">
<div id="first-row">
<div id="left">A</div>
<div id="splitter">B</div>
<div id="right">C</div>
</div>
<div>
<div>D</div>
<div>E</div>
<div>F</div>
</div>
</section>
There could be more examples from the same chunks of code and floatting children.
Clear the floats in the container.
You have 3 simple ways to do that:
1. Float
#container {
clear: both;
}
2. Overflow
#container {
overflow: hidden;
}
3. Micro clearfix hack
Link
Here is what you want done bro..
this one is by using display:inline-block https://jsfiddle.net/p4domjrb/
this one is by using float:left https://jsfiddle.net/p4domjrb/1/
.container {
background-color: #333333;
width: 990px;
display: block;
position: relative;
}
.left {
background-color: red;
width: 300px;
display: inline-block;
margin-left: -4px;
}
.splitter {
background-color: green;
width: 90px;
display: inline-block;
margin-left: -4px;
}
.right {
background-color: blue;
width: 200px;
display: inline-block;
margin-left: -4px;
}
don't use id I suggest use class isntead because idis called only once.
<style>
.container{
background-color: #333333;
width:990px;
display:block;
clear:both;
}
#left{
background-color: red;
width:300px;
float:left;
}
#splitter{
background-color: green;
width:90px;
float:left;
}
#right{
background-color: blue;
width: 200px;
float:left;
}
</style>
<body>
<div class="container">
<div id="left">A</div>
<div id="splitter">B</div>
<div id="right">C</div>
</div>
<div class="container">
<div id="left">D</div>
<div id="splitter">E</div>
<div id="right">F</div>
</div>
</body>
result is

CSS - How to arrange 9 boxes in 3 columns of 3?

I don't understand why I can't get these boxes to align horizontally. The second and third columns are beginning underneath the previous column. Can they be arranged horizontally without resorting to moving the columns with position: relative; bottom: 150px; type positioning or margins?
Here's the JSFiddle: https://jsfiddle.net/625nrqj7/
The HTML:
<div class="wrapper">
<div class="left-middle-blocks">
<div class="submenu-block-1"></div>
<div class="submenu-block-2"></div>
<div class="submenu-block-3"></div>
<div class="submenu-block-4"></div>
<div class="submenu-block-5"></div>
<div class="submenu-block-6"></div>
</div>
<div class="submenu-image-top"></div>
<div class="submenu-image-bottom"></div>
</div>
The CSS:
.submenu-image-top,.submenu-image-bottom,.submenu-block-1,.submenu-block- 2,.submenu-block-3,.submenu-block-4,.submenu-block-5,.submenu-block-6 {
width: 50px;
height: 50px;
}
.submenu-block-1,.submenu-block-2,.submenu-block-3 {
float: left;
clear: left;
background: red;
}
.submenu-block-4,.submenu-block-5,.submenu-block-6 {
float: right;
clear: right;
background: yellow;
}
.submenu-image-top,.submenu-image-bottom {
float: right;
clear: right;
background: blue;
}
.wrapper {
width: 250px;
}
.left-middle-blocks {
width: 150px;
}
Your question is very vague, but if I understand correctly you can achieve what you want by wrapping each three blocks in a different wrapper and setting:
.wrapper {
display: inline-block;
}
jsFiddle: → here.
Snippet:
.wrapper {
display: inline-block;
margin: 0 25px; /* To separate them */
}
.block {
width: 50px;
height: 50px;
border: 1px solid green; /* To make each square visible */
}
#block-1, #block-2, #block-3 {
background: red;
}
#block-4, #block-5, #block-6 {
background: yellow;
}
#block-7, #block-8, #block-9 {
background: blue;
}
<div class="wrapper">
<div id="block-1" class="block"></div>
<div id="block-2" class="block"></div>
<div id="block-3" class="block"></div>
</div>
<div class="wrapper">
<div id="block-4" class="block"></div>
<div id="block-5" class="block"></div>
<div id="block-6" class="block"></div>
</div>
<div class="wrapper">
<div id="block-7" class="block"></div>
<div id="block-8" class="block"></div>
<div id="block-9" class="block"></div>
</div>
If you want the boxes to stay inline use:
.block {
display: inline-block;
}
Snippet:
.wrapper, .block {
display: inline-block;
}
.wrapper {
margin: 0 15px;
/* To separate them */
}
.block {
width: 50px;
height: 50px;
border: 1px solid green;
/* To make each square visible */
}
#block-1, #block-2, #block-3 {
background: red;
}
#block-4, #block-5, #block-6 {
background: yellow;
}
#block-7, #block-8, #block-9 {
background: blue;
}
<div class="wrapper">
<div id="block-1" class="block"></div>
<div id="block-2" class="block"></div>
<div id="block-3" class="block"></div>
</div>
<div class="wrapper">
<div id="block-4" class="block"></div>
<div id="block-5" class="block"></div>
<div id="block-6" class="block"></div>
</div>
<div class="wrapper">
<div id="block-7" class="block"></div>
<div id="block-8" class="block"></div>
<div id="block-9" class="block"></div>
</div>

Resources