I am trying to apply different gap between each grid element, for example we are having the following code. 4 Grid lines, 3 Elements and a 10px width between each grid-box. How can i apply custom width between each grid-box? for example 20px between element1 and element2, and then 30px between element2 and element3?
Can i achieve that with the css grids?
Edit: Without using padding.
Edit2: Provided Pictre.
Click for picture preview
html, body {height: 100%; margin: 0; padding: 0;}
body {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-row: 1fr 1fr;
grid-column-gap: 10px;
grid-row-gap: 10px;
}
#element1 {
grid-column: 1/2;
grid-row: 1/2;
border: 1px solid #2e2e2e;
color: #000;
}
#element2 {
grid-column: 2/3;
grid-row: 1/2;
border: 1px solid #2e2e2e;
color: #000;
}
#element3 {
grid-column: 3/4;
grid-row: 1/2;
border: 1px solid #2e2e2e;
color: #000;
}
<div id="element1">element1</div>
<div id="element2">element2</div>
<div id="element3">element3</div>
Well the general approach that I like to use with css-grid is to make extra columns. Obviously use grid-column-gap and grid-row-gap if you have the same padding, but if not you can add token columns.
Why not padding/ margin?
You can totally use padding/ margin for this, but I like the extra column a bit better, since in css-grid you define the layout in the wrapper and this is where this belongs to semantically. You also do not have to apply it to every single item in those columns. (Also, do you apply it to the left or the right or both items?).
But this messes up my numbering
Yes, that is why you never use numbers to describe an area in css grid!
You can name your lines and with it your areas. Use this! You can use the grid-template-areas for this ore simply name it like this:
grid-template-columns: [left-start] auto [left-end right-start] auto [right-end];
Oh you want extra padding? Here you go:
grid-template-columns: [left-start] auto [left-end] 10px [right-start] auto [right-end];
Note that I am by no means a seasoned web developer (quite the opposite), but I think this approach might - generally - be the best one.
I don't see anything specific on Grid for your case, but you can easily achieve the desired result by adding padding.
HTML
<div id="grid">
<div id="element1">
<div class="content">element1</div>
</div>
<div id="element2">
<div class="content">element2</div>
</div>
<div id="element3">
<div class="content">element3</div>
</div>
</div>
CSS
#element1 {
padding-right: 5px;
}
#element2 {
padding-left: 5px;
padding-right: 10px;
}
#element3 {
padding-left: 10px;
}
.content {
height: 100%;
border: 1px solid #2e2e2e;
}
JsFiddle example:
https://jsfiddle.net/wkt39kk8/
Related
I am using CSS grid for a website, and in the information section I have 2 columns:
on the left a paragraph with information, on the right the image.
However, when I want to add an h1 to the paragraph it creates an extra column, resulting in:
On the left the header, on the right the image and underneath the header is now the paragraph.
I've now avoided the problem by using and making a class for the first sentence of the paragraph (making that sentence look like a h1) but it feels like a makeshift solution. Is there a better way to solve this problem?
I've tried 2fr 2fr, still the same problem
I've added a screenshot of what it looks like
(I'm still very new to CSS grid)
.block1{
display:grid;
grid-template-columns: 1fr 2fr;
column-gap: 250px;
background-color: #EFEDE3;
padding: 150px;
}
.block1 img{
justify-self: end;
border-radius: 5px;
width: 75%;
}
.block1 span {
font-weight: bolder;
font-size: 32px;
}
You can try this one.
HTML:
<div class="grid">
<div class="paragraph">
<h1>Paragraph</h1>
</div>
<div class="imageBox">
</div>
</div>
and CSS:
.grid {
display: grid;
grid-template-columns: 1fr 2fr;
column-gap: 250px;
}
.paragraph {
border: 1px solid green;
height: 40vh;
}
.imageBox {
border: 1px solid red;
height: 40vh;
}
Is this layout remotely possible in IE11 (very crude example)?
$(document).on('click', '.js-toggle-hide', function(e){
e.preventDefault();
$(this).parent().parent().find('.js-hide').toggle();
});
#charset "UTF-8";
.c-sidebar {
display: grid;
grid-template-columns: 120px auto;
outline: 1px solid #ccc;
overflow: auto;
}
.c-cat {
display: grid;
grid-template-columns: 120px auto;
grid-template-rows: auto;
}
.c-cat__name {
grid-row: 1 / 1000;
}
.c-cat__toggle {
grid-row: 1 / 999;
min-width: 120px;
}
.c-cat__subcat {
grid-column: 3 / 4;
min-width: 120px;
}
.c-cat__subcat--all {
grid-column: 2 / 4;
}
/* decoration */
body {
padding: 15px;
background: #eee;
font-size: 11px;
}
.c-cell {
background: #fff;
outline: 1px solid #ccc;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="c-sidebar">
<div class="c-cell">All Categories</div>
<div>
<div class="c-cat">
<div class="c-cat__name c-cell">Sales</div>
<div class="c-cat__toggle c-cell">
All items
</div>
<div class="c-cat__subcat c-cell js-hide">Export sales</div>
<div class="c-cat__subcat c-cell js-hide">Other sales</div>
<div class="c-cat__subcat c-cell js-hide">Product sales</div>
<div class="c-cat__subcat--all c-cell js-hide"><b>All items</b></div>
</div>
</div>
</div>
Note that the number of items in the right columns is undefined (types of sales), client can add/remove them.
Are there any css tricks I'm not aware of?
The alternative is to use tables with complex js/jquery code (this is just a part of the code but it represents my dilemma perfectly) and that would be very tedious work.
My recommendation is if you want to be grid modern and still support something like IE11....then start with in display: flex and then do a media support to add your grid like this:
#supports (display: grid) {
#_your css grid here _#
}
So then you can add all your grid there....you are not necessarily repeating if you do this you are just doing the grid part here(grid-template, columns, rows, etc) and bypass any other styling like color, font, px and etc...
I don't understand why DIV 3 is not the same size as DIV 1 + DIV 2.
https://codepen.io/anon/pen/vaVqPW
.grid {
display: grid;
grid-auto-columns: 1fr 1fr; /* I also tried 50% 50% */
grid-gap: 20px;
}
Firefox 61 should support css grid according to caniuse
https://caniuse.com/#feat=css-grid
* {
box-sizing: border-box;
}
.grid {
display: grid;
grid-auto-columns: 1fr 1fr;
grid-gap: 20px;
}
.content {
grid-column: 1;
background: red;
}
.sidebar {
grid-column: 2;
background: blue;
}
.grid>* {
/*border: 1px dashed red; */
/* demo only */
}
.box {
width: 50%;
height: 75px;
background-color: black;
color: #fff;
padding: 20px;
position: relative;
float: left;
}
.box100 {
width: 100%;
height: 75px;
color: #fff;
padding: 20px;
}
.box.arrow-left:after {
content: " ";
position: absolute;
left: -15px;
margin-top: -15px;
top: 50%;
border-top: 15px solid transparent;
border-right: 15px solid black;
border-left: none;
border-bottom: 15px solid transparent;
}
<div class="grid">
<div class="content">
<div class="box" style="background:gray">
DIV 1 (50% of column 1)
</div>
<div class="box arrow-left">
DIV 2 (50% of column 1)
</div>
</div>
<div class="sidebar">
<div class="box100">DIV 3 (100% of column 2)</div>
</div>
</div>
<div>
<div class="content" style="background:tomato">
<p>content 4 (100% of column 1 + GAP + 100% of column 2 )</p>
</div>
</div>
Firefox does indeed support CSS Grid (see caniuse.com).
The problem is that Firefox does not appear to support multiple values in grid-auto-columns.
This is your code in Chrome. No problems.
This is your code in Firefox. There's a problem. The code is invalid / not recognized.
It fails in Firefox here, too:
The grid-auto-columns property can take multiple values, per the spec definition. However, Firefox appears to lack support for this set-up. It only accepts a single value.
Your correction to the problem, as stated in your answer and copied below, is simply to switch from implicit columns (grid-auto-columns) to explicit columns (grid-template-columns).
grid: auto-flow dense / 1fr 1fr;
The grid property is a shorthand property that allows you to set all explicit and implicit rules in a single declaration. Your rule above breaks down to this:
So in the end, it appears that a simple switch from grid-auto-columns to grid-template-columns was all you needed.
grid: auto-flow dense / 1fr 1fr;
this seems to solve the Problem!
At the same time deleting the line:
grid-auto-columns: 1fr 1fr;
Pen is updated: https://codepen.io/anon/pen/vaVqPW
I'm trying to create a layout with CSS grid that looks like this (ie: a section on the left that has a fixed width and height, a section at the top which takes up the minimum height possible, and a section underneath that which takes up all the remaining space):
However, what I'm getting is this (where the space at the bottom of the orange section is equal to the grid-row-gap):
I'm wondering why the fr is being calculated like this instead of compensating for the grid gap?
(In my project I can fix this issue by adding a margin to the bottom right element instead of using grid-row-gap, but I'd like to know if there's something I'm misunderstanding about CSS grid)
span {
display: inline-block;
}
.grid {
border: 1px solid black;
display: inline-grid;
grid-template-columns: repeat(2, auto);
grid-template-rows: auto 1fr;
grid-row-gap: 1rem;
}
.left {
background: orange;
height: 120px;
width: 120px;
grid-row: 1/span 2;
}
.right-top {
background: yellow;
height: 20px;
width: 300px;
}
.right-bottom {
background: blue;
}
<div class="grid">
<span class="left"></span>
<span class="right-top"></span>
<span class="right-bottom"></span>
</div>
I'm experimenting with CSS Grids, and this is the layout I'm building:
.grid {
display: grid;
align-items: center;
grid-template-columns: 1fr 4rem 1fr;
grid-template-rows: 1rem 1fr 1rem;
max-width: 900px;
margin: 0 auto;
}
.text {
/*
// Ideally, this should be
grid-area: text
*/
grid-column: 1 / 3;
grid-row: 2 / 3;
/* Fix z-index */
position: relative;
padding: 4rem;
background-color: #fff;
}
.image {
/*
// Ideally, this should be
grid-area: image;
*/
grid-column: 2 / 4;
grid-row: 1 / -1;
background-color: lightgray;
padding: 1rem;
/* Center das image */
display: flex;
justify-content: center;
}
/* Basic body */
body {
background-color: #fafafa;
font-family: sans-serif;
padding: 2rem;
}
img {
max-width: 100%;
height: auto;
}
<div class="grid">
<div class="text">One morning, when bobby woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. He lay on his leg like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into
stiff sections.
</div>
<div class="image">
<img src="http://unsplash.it/400/400" />
</div>
</div>
(best to preview in full page...)
What I'd like to avoid:
.text and .image both currently are using grid-column: * / *; syntax, instead I'd like to use grid-area: text and grid-area: image;.
Is it possible to define grid-template-{columns|rows} as overlapping areas? I tried using second way of defining grid areas
, but that didn't seem to work.
Looks like you can't do [a-start] [b-start] [a-end] [b-end] in that syntax, or at least I didn't manage to.
So - Is there any way to create an overlapping grid using named areas?
I'm trying to use the named areas for convenience purely - so that it's easier to reason about the responsive layout code, instead of repeating myself multiple times in media queries.
Edit
Found the answer because of #vals answer below.
This seemed to work just fine, I probably made a syntax error in my previous attempt somewhere:
grid-template-columns: [text-start] 1fr [image-start] 4rem [text-end] 1fr [image-end];
grid-template-rows: [image-start] 1rem [text-start] 1fr [text-end] 1rem [image-end];
At least in a more basic layout, it seems to work for me:
.container {
border: solid 1px green;
height: 180px;
width: 300px;
display: grid;
grid-template-columns: [left-start] 100px [right-start] 100px [left-end] 100px [right-end];
grid-template-rows: [left-start] 60px [right-start] 60px [left-end] 60px [right-end];
}
.left {
grid-area: left;
background-color: red;
}
.right {
grid-area: right;
background-color: lightgray;
opacity: 0.5;
}
<div class="container">
<div class="left">
</div>
<div class="right">
</div>
</div>