How to repeat display grid area for n element - css

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>

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>

How to set equal width for flex elements?

Why blocks .b have different width? How to set it equal?
.parent {
display: flex;
}
.parent>div {
flex: 1 1 auto;
}
.parent .b {
display: flex;
}
<div class="parent">
<div class="cell">
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
<div>
Why blocks <div class="cell"> have different width?
Edit: use CSS grid and auto-fit:
.parent {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.parent {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.parent>div {
background-color: lightblue;
margin-left: 5px;
}
<div class="parent">
<div class="cell">
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
</div>
Second re-edit**
First choice you can do is just set a flex on the parent element as this will only effect the first element below that, which in this case is the cell class, i will add a border on the cell class so you can see this in effect
<div class="parent">
<div class="cell">
<div class="b"></div>
</div>
<div class="cell">
<div class="b"></div>
</div>
<div class="cell">
<div class="b"></div>
</div>
<div class="cell">
<div class="b"></div>
</div>
<div>
.parent {
display: flex;
width: 70%;
}
.cell {
width: 20%;
height: 100px;
border: 1px solid orange;
}
here you can set the size of your parent width which will be the size across your screen, you can then set the width of the .cell childs and they will all then be the same, but only at a maximum of the parent
** second option you can do
Here is a simpler version, and i have added 3 different classes to show how you can choose the sizing you want
<div class="parent">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
<div>
.parent {
display: flex;
width: 80%;
height: 100px;
}
.a {
flex: 40%;
border: 1px solid greenyellow;
}
.b {
flex: 20%;
border: 1px solid orange;
}
.c {
flex: 20%;
border: 1px solid blue;
}
Of course you can change them back and have them all be called the same class, and just assign one width and again they will all be the same... i hope this helps
I think they all are in same width. You need to use this css instead of the .parent>div selector
.cell {
flex: 1 1 auto;
}
.parent {
display: flex;
}
.cell {
flex: 1 1 auto;
}
.parent .b {
display: flex;
align-items: center;
justify-content: center;
}
.b {
height: 50px;
}
.cell:nth-child(1) {
background: red;
}
.cell:nth-child(2) {
background: yellow;
}
.cell:nth-child(3) {
background: green;
}
.cell:nth-child(4) {
background: teal;
}
<div class="parent">
<div class="cell">
<div class="b">hi</div>
</div>
<div class="cell">
<div class="b">hi</div>
</div>
<div class="cell">
<div class="b">hi</div>
</div>
<div class="cell">
<div class="b">hi</div>
</div>
<div>

Vertical scroll bar in div which is a child of css grid column

I am new to CSS grid, I have a nested grid layout page. I could not get a scroll bar for grid child div.fieldsContainer.
html,body,
.wrapper{
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.wrapper{
display: grid;
grid-template-rows: 50px 1fr 50px;
}
.header{
border: 1px solid #ddd;
background: lightyellow;
}
.footer{
background: lightpink;
}
.content{
display: grid;
grid-template-columns: 250px 1fr 300px;
grid-gap: 10px;
overflow: hidden;
}
.fieldTypes{
display: grid;
grid-template-rows: 40px 1fr;
}
.fieldTypes .search{
border: 1px solid red;
}
.fieldTypes .fieldsContainer{
display: grid;
grid-template-columns: repeat(3, minmax(70px,1fr));
grid-auto-rows: 50px;
grid-gap: 10px;
}
.card{
padding: 10px;
background: #ddd;
}
<div class="wrapper">
<div class="header">
Header
</div>
<div class="content">
<div class="fieldTypes">
<div class="search">search</div>
<div class="fieldsContainer">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
<div class="card">9</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
</div>
</div>
<div class="inndercontent">
innder content
</div>
<div class="graphs">
graphs
</div>
</div>
<div class="footer">
Footer
</div>
</div>
One solution would be to set overflow-y:auto on the parent ( .fieldTypes ) and overflow-y:scroll on .fieldsContainer
There is no ' story ' behind this. Just that you have to set a default overflow for the parent to accept it, and then specify overflow-y:scroll( as you want vertical scroll ) on the child.
html,body,
.wrapper{
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.wrapper{
display: grid;
grid-template-rows: 50px 1fr 50px;
}
.header{
border: 1px solid #ddd;
background: lightyellow;
}
.footer{
background: lightpink;
}
.content{
display: grid;
grid-template-columns: 250px 1fr 300px;
grid-gap: 10px;
overflow: hidden;
}
.fieldTypes{
display: grid;
grid-template-rows: 40px 1fr;
overflow-y:auto;/*added*/
}
.fieldTypes .search{
border: 1px solid red;
}
.fieldTypes .fieldsContainer{
display: grid;
grid-template-columns: repeat(3, minmax(70px,1fr));
grid-auto-rows: 50px;
grid-gap: 10px;
overflow-y:scroll;/*added*/
}
.card{
padding: 10px;
background: #ddd;
}
<div class="wrapper">
<div class="header">
Header
</div>
<div class="content">
<div class="fieldTypes">
<div class="search">search</div>
<div class="fieldsContainer">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
<div class="card">9</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
</div>
</div>
<div class="inndercontent">
innder content
</div>
<div class="graphs">
graphs
</div>
</div>
<div class="footer">
Footer
</div>
</div>
Here's a more reduced case (to cut through the irrelevant parts)
html, body, .A {
height: 100%; /* matters */
width: 100%;
margin: 0;
padding: 0;
}
.A {
max-height: 300px; /* matters */
display: grid; /* matters */
overflow: hidden; /* matters */
}
.B {
display: grid; /* matters */
overflow-y: auto; /* matters */
}
.D {
overflow-y: scroll; /* matters */
}
.C {
padding: 10px;
background-color: #07f;
}
.E {
padding: 10px;
background-color: #eee;
}
<div class="A">
<div class="B">
<div class="C">search</div>
<div class="D">
<div class="E">1</div>
<div class="E">2</div>
<div class="E">3</div>
<div class="E">4</div>
<div class="E">5</div>
<div class="E">6</div>
<div class="E">7</div>
<div class="E">8</div>
<div class="E">9</div>
<div class="E">10</div>
<div class="E">11</div>
<div class="E">12</div>
<div class="E">10</div>
<div class="E">11</div>
<div class="E">12</div>
<div class="E">10</div>
<div class="E">11</div>
<div class="E">12</div>
</div>
</div>
</div>
Set the parent's height to 100vh. Then overflow-y: scroll will work on the children.
See this example (based on the reduced case answer).
html, body, .A {
margin: 0;
padding: 0;
}
.A {
height: 100vh; /* matters */
display: grid; /* matters */
}
.B {
padding: 10px;
background-color: #07f;
}
.C {
overflow-y: scroll; /* matters */
}
.D {
padding: 10px;
background-color: #eee;
}
<div class="A">
<div class="B">search</div>
<div class="C">
<div class="D">1</div>
<div class="D">2</div>
<div class="D">3</div>
<div class="D">4</div>
<div class="D">5</div>
<div class="D">6</div>
<div class="D">7</div>
<div class="D">8</div>
<div class="D">9</div>
<div class="D">10</div>
<div class="D">11</div>
<div class="D">12</div>
<div class="D">10</div>
<div class="D">11</div>
<div class="D">12</div>
<div class="D">10</div>
<div class="D">11</div>
<div class="D">12</div>
</div>
</div>

Empty cell in flexbox

There is a usual flexbox with the elements:
.flexbox {
display: flex;
border: 2px solid red;
padding: 2.5px;
}
.flexbox__item {
border: 2px solid blue;
height: 50px;
margin: 2.5px;
flex-grow: 1;
}
<div class="flexbox">
<div class="flexbox__item"></div>
<div class="flexbox__item offset-1"></div>
<div class="flexbox__item"></div>
</div>
How to insert an empty cell in this flexbox after .offset-* without using additional markup and after with before?
Those. It is necessary that it come out like this, but without specifying the width of the blocks. Only flex-grow
.flexbox {
display: flex;
border: 2px solid red;
padding: 2.5px;
}
.flexbox__item {
border: 2px solid blue;
height: 50px;
margin: 2.5px;
width: 25%;
}
.offset-1 {
margin-right: calc(25% + 5px);
}
<div class="flexbox">
<div class="flexbox__item"></div>
<div class="flexbox__item offset-1"></div>
<div class="flexbox__item"></div>
</div>
The number of cells is unknown. Offset-1 means that you need to make an empty one cell,offset-2 means two cell, and so on.
It is possible with additional wrappers - the wrappers will grow, and the cell elements inside the growing wrappers will occupy 1/2, 1/3, etc. of the width of the wrappers.
.flexbox {
display: flex;
border: 2px solid red;
padding: 3px;
}
.flexbox__item {
margin: 3px;
flex-grow: 1;
}
.flexbox__item-inner {
border: 2px solid blue;
height: 50px;
}
.offset-1 {
flex-grow: 2;
}
.offset-1 .flexbox__item-inner {
width: 50%;
}
.offset-2 {
flex-grow: 3;
}
.offset-2 .flexbox__item-inner {
width: 33.33%;
}
<div class="flexbox">
<div class="flexbox__item">
<div class="flexbox__item-inner"></div>
</div>
<div class="flexbox__item offset-1">
<div class="flexbox__item-inner"></div>
</div>
<div class="flexbox__item">
<div class="flexbox__item-inner"></div>
</div>
</div>
<div class="flexbox">
<div class="flexbox__item">
<div class="flexbox__item-inner"></div>
</div>
<div class="flexbox__item offset-2">
<div class="flexbox__item-inner"></div>
</div>
<div class="flexbox__item">
<div class="flexbox__item-inner"></div>
</div>
</div>

Horizontally align elements with different height

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>

Resources