CSS grid - start all coumns from start with auto height on each - css

I want to have columns in which X amount of items can be placed and i want them to start from position 0 and stack up with auto height:
<!DOCTYPE html>
<html>
<head>
<style>
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
background-color: #2196F3;
padding: 10px;
align-items:start;
}
.grid-item {
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.8);
padding: 20px;
font-size: 30px;
text-align: center;
}
.item-1{grid-column-start:1; grid-column-end:1; grid-auto-rows: auto;}
.item-2{grid-column-start:1; grid-column-end:1; grid-auto-rows: auto;}
.item-3{grid-column-start:2; grid-column-end:2; grid-auto-rows: auto;}
.item-4{grid-column-start:3; grid-column-end:3; grid-auto-rows: auto;}
</style>
</head>
<body>
<div class="grid-container">
<div class="grid-item item-1">1</div>
<div class="grid-item item-1">2</div>
<div class="grid-item item-3">3</div>
<div class="grid-item item-4">4</div>
</div>
</body>
</html>
JSfiddle
This is a drawing what i want to achieve:
Wanted result image

Using flex box you can do something like this :
.style {
border: 5px solid black;
}
.grid-container {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.grid-item {
height: 200px;
width: 20%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.item {
width: 100%;
height: 50px;
}
.item-spe {
height: 50px
}
<div class="grid-container">
<div class="grid-item">
<div class="item style"></div>
<div class="item style"></div>
<div class="item style"></div>
</div>
<div class="grid-item style"></div>
<div class="grid-item style item-spe"></div>
<div class="grid-item style"></div>
</div>

Related

Trying to find display: contents alternative that I can use with my CSS grid

I have a grid that uses display: contents. Unfortunately, this declaration still isn't widely supported. I'm trying to substitute it with something that's more widely supported and that wouldn't break my current grid design. Any help would be greatly appreciated.
Here's the code:
.grid-row {
display: contents;
}
.grid-row:hover > div {
background-color: #262626;
color: #fff;
}
.grid-cell {
background-color: #000;
color: #808080;
padding: .5rem;
min-height: 4rem;
display: flex;
align-items: center;
justify-content: flex-start;
position: relative;
}
.grid {
margin: 0 auto;
display: grid;
grid-gap: 1px;
background-color: #808080 !important;
border: 1px solid #808080 !important;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: auto min-content min-content;
white-space: pre-wrap !important;
}
<div class="grid">
<div class="grid-cell"></div>
<div class="grid-cell">Price</div>
<div class="grid-cell">Quantity</div>
<div class="grid-row">
<div class="grid-cell">Item 1</div>
<div class="grid-cell">10.00</div>
<div class="grid-cell">1</div>
</div>
<div class="grid-row">
<div class="grid-cell">Item 2</div>
<div class="grid-cell">20.00</div>
<div class="grid-cell">2</div>
</div>
<div class="grid-row">
<div class="grid-cell">Item 3</div>
<div class="grid-cell">30.00</div>
<div class="grid-cell">3</div>
</div>
</div>
You could convert it into table:
.grid-row {
display: table-row;
}
.grid-row:hover > div {
background-color: #262626;
color: #fff;
}
.grid-cell {
background-color: #000;
color: #808080;
padding: .5rem;
line-height: 4rem;
display: table-cell;
position: relative;
}
.grid {
margin: 0 auto;
display: table;
background-color: #808080 !important;
white-space: pre-wrap !important;
border-spacing: 1px;
}
.grid > :first-of-type
{
width: 100%;
}
<div class="grid">
<div class="grid-cell"></div>
<div class="grid-cell">Price</div>
<div class="grid-cell">Quantity</div>
<div class="grid-row">
<div class="grid-cell">Item 1</div>
<div class="grid-cell">10.00</div>
<div class="grid-cell">1</div>
</div>
<div class="grid-row">
<div class="grid-cell">Item 2</div>
<div class="grid-cell">20.00</div>
<div class="grid-cell">2</div>
</div>
<div class="grid-row">
<div class="grid-cell">Item 3</div>
<div class="grid-cell">30.00</div>
<div class="grid-cell">3</div>
</div>
</div>

CSS - Flex elements with margin right

I want to create a grid of blocks using css flex.
The blocks need to be in three columns and they should be a 3rd of the width of the parent container.
My problem is I need a right margin on the blocks.
The blocks need to be a percentage of the container so I cant use space between.
.block {
border: 1px solid lightgrey;
display: flex;
flex-wrap: wrap;
padding: 5px;
max-width: 900px;
}
.block__item {
background: grey;
height: 20px;
margin-right: 2px;
//margin-bottom: 2px;
width: 33.33%;
}
.block__item:nth-child(3n){
margin-right: 0;
}
<div class="block">
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
</div>
A bit late to the party, but I found a working hack:
Have the overflow auto on a container element around it and give the element itself an invisible border of 8px on the side(s) where you expect the scrollbar to appear. When the scrollbar does show, it will be displayed on top of the invisible border instead of on top of the content.
Judging by your question, I believe this is what you are trying to accomplish:
.block {
border: 1px solid lightgrey;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
padding: 5px;
max-width: 900px;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
.block__item {
background: grey;
height: 20px;
margin-right: 2px;
margin-bottom: 2px;
width: 33%;
}
<div class="block">
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
</div>
I added the vendor prefixes so that it displays consistently across all browsers. You can adjust the spacing between boxes by adjusting the percentage (i.e. 31% width). If you plan on using Flexbox often you should check out this site for quick vendor versions: http://the-echoplex.net/flexyboxes/
Maybe you can simply decrease the width of the blocks, and the rest of the witdh assign it to the margin.
Like this:
.block__item {
background: grey;
height: 20px;
margin-right: 3%;
width: 30%;
}
The problem is the padding on the container. But you can use width: calc((100% - 10px) / 3); to calculate the correct 33,33% of the container width excluding the padding.
.block {
border: 1px solid lightgrey;
display: flex;
flex-wrap: wrap;
padding: 5px;
max-width: 900px;
}
.block__item {
background: grey;
height: 20px;
margin-right: 2px;
margin-bottom: 2px;
width: calc((100% - 10px) / 3);
}
.block__item:nth-child(3n){
margin-right: 0;
}
<div class="block">
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
</div>
Very Good Question
.block {
border: 1px solid lightgrey;
display: flex;
flex-wrap: wrap;
max-width: 900px;
margin-left: -1px;
margin-right: -1px;
}
.block__item {
background: grey;
background-clip: content-box;
height: 20px;
flex-basis: 33.33%;
box-sizing: border-box;
padding-left: 1px;
padding-right: 1px;
margin-bottom: 2px;
}
<div class="block">
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
<div class="block__item"></div>
</div>
Actually, it's good practice to split layout and content in html.
.b-row {
display: flex;
flex-wrap: wrap;
margin-left: -1px;
margin-right: -1px;
}
.b-row > .b-col {
flex-basis: 33.33%;
box-sizing: border-box;
padding-left: 1px;
padding-right: 1px;
margin-bottom: 2px;
}
.block__item {
background-color: grey;
height: 20px;
}
<div class="block">
<div class="b-row">
<div class="b-col">
<div class="block__item">asdfasfasdf</div>
</div>
<div class="b-col">
<div class="block__item">asdfasfdasf</div>
</div>
<div class="b-col">
<div class="block__item">asdfasdfas</div>
</div>
<div class="b-col">
<div class="block__item">asdfasdfa</div>
</div>
<div class="b-col">
<div class="block__item">asdfasdfadsf</div>
</div>
</div>
</div>
Anyway, you can choose your preference.

flexbox item 100% of remaining width

I want to achieve the following scenario with flexbox
the green element is a text element and the width is flexible. The blue elements should have 100% of the remaining width beside the green element.
My current solution looks like this:
<div class="container">
<span class="title">title</span>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
and the css:
.container {
display: flex;
align-items: center;
flex-wrap: wrap;
background-color: #EAEBEF;
.title {
padding: 20px;
background-color: #48CFAE;
}
.fullwidth {
background-color: #87BDFF;
flex: 0 0 100%;
height: 60px;
margin: 10px 0;
}
}
But it looks currently like this
here is a codepen example
Without changing the HTML this can be managed with CSS-Grid as an alternative to flexbox.
.container {
display: grid;
grid-template-columns: max-content 1fr;
grid-gap: 1em;
background-color: #EAEBEF;
margin-bottom: 1em;
}
.title {
padding: 10px;
grid-row: 2;
background-color: #48CFAE;
}
.fullwidth {
grid-column: 2;
background-color: #87BDFF;
height: 40px;
}
<div class="container">
<div class="title">title</div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
<div class="container">
<div class="title">Longer title</div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
Try this HTML and CSS markup. Basically You need to keep the left side in one div and the right side elements in another div.
.container {
display: flex;
align-items: center;
flex-wrap: nowrap;
background-color: #eaebef;
}
.container .title {
padding: 20px;
background-color: #48cfae;
}
.container .div1 {
width: 20%;
}
.container .div2 {
width: 80%;
}
.container .fullwidth {
background-color: #87bdff;
height: 60px;
margin: 10px 0;
}
<div class="container">
<div class="div1">
<span class="title">title</span>
</div>
<div class="div2">
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
</div>
See code below:
You have to warp fullwidth in div and set width to this div
also set width and margin to title
.container {
display: flex;
align-items: center;
flex-wrap: wrap;
background-color: #EAEBEF;
}
.title {
width: 20%;
padding: 20px;
background-color: #48CFAE;
margin-left: 15px;
}
.fullwidth {
background-color: #87BDFF;
flex: 0 0 100%;
height: 60px;
margin: 10px 0;
}
.a{
margin: 50px;
width: 50%;
}
<div class="container">
<span class="title">title</span>
<div class="a">
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
</div>
If you want to achive this without change your html but only your less, try this:
.container {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
background-color: #EAEBEF;
justify-content: flex-end;
.title {
padding: 20px;
background-color: #48CFAE;
margin-right: 20px;
flex-grow: 1
}
.fullwidth {
background-color: #87BDFF;
height: 60px;
margin: 10px 0;
width: 80%;
}
}
your codepen edited

ie 11: flex grow parent issue

I have such code:
https://plnkr.co/edit/ZAEzfAOCO0ZcSq2OR4Lp?p=preview
but this isn't working in ie, until I add height:0 (it's a very bad idea on parent element)
<body>
<div class="container">
<div class="container-item container-item-1"></div>
<div class="container-item container-item-2"></div>
<div class="container-item container-item-3"></div>
</div>
</body>
body, html {
min-height: 100%;
height: 100%;
}
.container {
width: 100%;
min-height: calc(100% - 80px);
margin: 30px;
padding: 20px;
border: 1px solid gray;
border-radius: 16px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
.container-item {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
content: "someText";
border-bottom: 1px solid #cecece;
}
.container-item-1 {
background-color: red;
}
.container-item-2 {
background-color: orange;
}
.container-item-3 {
background-color: green;
}
everything works fine in chrome and ff
(my parents should expand to fit parent)
Important!
I need a flexible solution, my code can have a lot of nested div's (not a constant value) between body and content divs.
for example:
<body>
<div>
<div>
<div class="container">
<div class="container-item container-item-1"></div>
<div class="container-item container-item-2"></div>
<div class="container-item container-item-3"></div>
</div>
</div>
</div>
</body>
or
<body>
<div>
<h3>text</h3>
<div class="container">
<div class="container-item container-item-1"></div>
<div class="container-item container-item-2"></div>
<div class="container-item container-item-3"></div>
</div>
</div>
</body>
If you have an unknown or nested markup before the container, you could add an extra wrapper within it (here inner), to overcome IE's min-height bug.
Fiddle sample 1 -- Fiddle sample 2
Stack snippet sample 1
html, body {
margin: 0;
}
.container {
display: flex;
}
.container .inner {
width: 100%;
min-height: calc(100vh - 100px);
margin: 30px;
padding: 20px;
border: 1px solid gray;
border-radius: 16px;
display: flex;
flex-direction: column;
}
.container-item {
flex-grow: 1;
border: 1px solid #cecece;
}
.container-item-1 {
background-color: red;
}
.container-item-2 {
background-color: orange;
}
.container-item-3 {
background-color: green;
}
<div>
<h3>text</h3>
<div class="container">
<div class="inner">
<div class="container-item container-item-1">
</div>
<div class="container-item container-item-2">
</div>
<div class="container-item container-item-3">
</div>
</div>
</div>
</div>
Stack snippet sample 2
html, body {
margin: 0;
}
.container {
display: flex;
}
.container .inner {
width: 100%;
min-height: calc(100vh - 100px);
margin: 30px;
padding: 20px;
border: 1px solid gray;
border-radius: 16px;
display: flex;
flex-direction: column;
}
.container-item {
flex-grow: 1;
border: 1px solid #cecece;
}
.container-item-1 {
background-color: red;
}
.container-item-2 {
background-color: orange;
}
.container-item-3 {
background-color: green;
}
<div>
<div>
<div class="container">
<div class="inner">
<div class="container-item container-item-1">
</div>
<div class="container-item container-item-2">
</div>
<div class="container-item container-item-3">
</div>
</div>
</div>
</div>
</div>

CSS Flexbox - varying height of elements on wrap

I have a simple layout with varying size elements that I am trying to put together for a dashboard.
div {
padding: 5px 5px 5px 5px;
margin: 1px 1px 1px 1px;
display: flex;
}
div.first {
border: 1px dotted lightpink;
}
div.second {
border: 1px dotted orange;
}
div.third {
border: 1px dotted green;
}
div.fourth {
border: 1px dotted fuchsia;
}
<div style="display: flex; height: 500px">
<div class="first" style="flex: 0 60%;flex-wrap: wrap;align-items;stretch;align-content:stretch">
<div class="first" style="flex: 1 100%; align-self: flex-start">
Title text
</div>
<div class="second" style="flex: 2 auto">
Content A
</div>
<div class="third" style="flex: 1 auto">
Content B
</div>
<div class="fourth" style="flex: 1 auto">
<div style="height: 66px; align-self:flex-end">
<div style="align-self: flex-end">
Content C
</div>
</div>
</div>
</div>
<div class="second" style="flex: 1 auto; align-items: flex-end">
Content D
</div>
</div>
Codepen link:
http://codepen.io/korgmatose/pen/qqKzry?editors=1100
I want to fill the second row (Content A,B,C) so that it starts just beneath Title Text.
But making align-items flex-start will not allow the second row to fill the remaining space, and setting a height to 100% on one of the items in that row only sets the height to the parent container, thus rendering the div's outside the bottom border.
Like #kukkuz said I would also recommend doing it this way. Just put the content A, B, C in a separate container, in this case #content and add display: flex, flex-direction: column and flex: 1 to it and please do not use inline styling for styling your HTML since it makes your code muss less readable. Most recommended way is to put your CSS code into a separate file and link it to your HTML.
The following code is an example of how you could do the markup of your desired layout without any inline styles.
HTML
<div id="wrapper">
<div class="left">
<div class="title">Title text</div>
<div id="content">
<div class="second">Content A</div>
<div class="third">Content B</div>
<div class="fourth">Content C</div>
</div>
</div>
<div class="right">Content D</div>
</div>
CSS
div {
padding: 5px 5px 5px 5px;
margin: 1px 1px 1px 1px;
}
#wrapper {
display: flex;
height: 500px;
}
.left {
flex: 3;
display: flex;
flex-direction: column;
}
#content{
flex: 1;
display: flex;
padding: 0;
}
.second,
.third,
.fourth {
flex: 1;
}
.third {
border: 1px dotted green;
}
.fourth {
display: flex;
align-items: flex-end;
border: 1px dotted fuchsia;
}
.right {
flex: 2;
}
.left,
.title {
border: 1px dotted lightpink;
}
.right,
.second {
border: 1px dotted orange;
}
div {
padding: 5px 5px 5px 5px;
margin: 1px 1px 1px 1px;
}
#wrapper {
display: flex;
height: 500px;
}
.left {
flex: 3;
display: flex;
flex-direction: column;
}
#content {
flex: 1;
display: flex;
padding: 0;
}
.second,
.third,
.fourth {
flex: 1;
}
.third {
border: 1px dotted green;
}
.fourth {
display: flex;
align-items: flex-end;
border: 1px dotted fuchsia;
}
.right {
flex: 2;
}
.left,
.title {
border: 1px dotted lightpink;
}
.right,
.second {
border: 1px dotted orange;
}
<div id="wrapper">
<div class="left">
<div class="title">Title text</div>
<div id="content">
<div class="second">Content A</div>
<div class="third">Content B</div>
<div class="fourth">Content C</div>
</div>
</div>
<div class="right">Content D</div>
</div>
div {
padding: 5px 5px 5px 5px;
margin: 1px 1px 1px 1px;
display: flex;
}
div.first {
border: 1px dotted lightpink;
}
div.second {
border: 1px dotted orange;
}
div.third {
border: 1px dotted green;
}
div.fourth {
border: 1px dotted fuchsia;
}
<div style="display: flex;">
<div class="first" style="flex: 0 60%;flex-wrap: wrap;align-items;stretch;align-content:stretch">
<div class="first" style="flex: 1 100%; align-self: flex-start">
Title text
</div>
<div class="second" style="flex: 2 auto">
Content A
</div>
<div class="third" style="flex: 1 auto">
Content B
</div>
<div class="fourth" style="flex: 1 auto">
<div style="height: 66px; align-self:flex-end">
<div style="align-self: flex-end">
Content C
</div>
</div>
</div>
</div>
<div class="second" style="flex: 1 auto; align-items: flex-end">
Content D
</div>
</div>
Something like this?

Resources