I am trying to build "adjustable" css grid. I am making my blog and i want my news to be displayed in "blocks" and that they me placed like this :
http://pokit.org/get/img/1dfa7b74c6be5bee6c92b886e0b8270b.jpg
And not like this what i did made here
Here is my code.
HTML
<div id="wrapper">
<div class="d_1">1</div>
<div class="d_2">2</div>
<div class="d_3">3</div>
<div class="d_4">4</div>
<div class="d_5">5</div>
<div class="d_6">6</div>
</div>
CSS
#wrapper{
width:200px;
}
#wrapper div{
background-color:lightgray;
width:50px;
float:left;
margin:0px 5px 5px 0px;
}
.d_1{
height:60px;
}
.d_2{
height:30px;
}
.d_3{
height:33px;
}
.d_4{
height:70px;
}
.d_5{
height:60px;
}
.d_6{
height:40px;
}
I suppose that is not possible to obtain the desired result simply using one of the known layout modes (flexbox, grid-layout, inline, ...) nor using CSS columns. Every solution will lead to an unwanted result.
But you can obtain the result using a combination of CSS grid-layout and Javascipt code.
This is the wrapper CSS style block:
#wrapper{
width: 200px; /* CSS grid-layout will expand contained divs to cover this size */
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* "1fr" for each column */
grid-column-gap: 10px;
grid-row-gap: 5px;
}
And this is the Javascript code (add it after #wrapper is closed):
"strict mode";
Array.prototype.max = function() {
return Math.max.apply(null, this);
};
function compute_gaps(a) {
let max = a.max();
return a.map(function(el) {
return el - max;
});
}
function compose_gaps(a, b) {
return b.map(function(el, i) {
return a[i] + el;
});
}
var counter = 0;
var columns = 3; // number of columns
var gaps = [];
var heights = [];
for (let el of document.querySelectorAll("#wrapper > div")) {
let colIdx = counter % columns;
if (counter % columns === 0) {
//compute gaps
if (counter) gaps.push(compute_gaps(heights));
if (gaps.length > 1) {
gaps[gaps.length - 1] = compose_gaps(
gaps[gaps.length - 1],
gaps[gaps.length - 2]
);
}
heights = [];
}
if (gaps.length) {
el.style.marginTop = gaps[Math.floor(counter / columns - 1)][colIdx];
}
heights.push(el.offsetHeight); // apply gap as margin
counter++;
}
Tested the code in a little more complex situation and worked in this way.
The code computes, in each row, gaps between the highest block and the others in the row (compute_gaps); after that, applied the gap as a CSS margin-top. Gaps are summed with the previous ones (compose_gaps).
I hope this answers your question.
Warning:
I am not the best at CSS and JS right now. I tend to brute force things until they work. I am pretty sure this is not the best solution, however, I want to post it so that maybe others can improve upon it. This may not be functional once all content is put in or may not by responsive or may not be dynamic enough to solve the issue, I don't know. I do know that the desired look from the question is achieved through this method, right now, without content etc.
I do welcome any and all feedback regarding why this isn't the best and/or what is wrong with it so I can learn.
With that being said, here is the fiddle:
http://jsfiddle.net/jz4p4Lzk/13/
HTML
<div id="wrapper">
<div class="d_1" id="d1">1</div>
<div class="d_2" id="d2">2</div>
<div class="d_3" id="d3">3</div>
<div class="d_4" id="d4">4</div>
<div class="d_5" id="d5">5</div>
<div class="d_6" id="d6">6</div>
CSS
#wrapper{
width:200px;
}
#wrapper div{
background-color:lightgray;
width:50px;
position:relative;
margin:0px 5px 5px 0px;
}
.d_1{
height:60px;
}
.d_2{
height:30px;
}
.d_3{
height:33px;
}
.d_4{
height:70px;
}
.d_5{
height:60px;
}
.d_6{
height:40px;
}
JS
var d1 = document.getElementById('d1');
var d1Loc = d1.getBoundingClientRect();
var d2 = document.getElementById('d2');
var d2Loc = d2.getBoundingClientRect();
var d3 = document.getElementById('d3');
var d3Loc = d3.getBoundingClientRect();
var d4 = document.getElementById('d4');
var d4Loc = d4.getBoundingClientRect();
var d5 = document.getElementById('d5');
var d5Loc = d5.getBoundingClientRect();
var d6 = document.getElementById('d6');
d2.style.left = d1Loc.right -5+ "px";
d2.style.top = - d1.offsetHeight - 5 + "px";
d3.style.left = d2Loc.right + d1Loc.right -10 +"px";
d3.style.top = - d1.offsetHeight - d2.offsetHeight - 10 + "px";
d4.style.top = - d1.offsetHeight - d2.offsetHeight - d3.offsetHeight + 50 + "px";
d5.style.top = - d1.offsetHeight - d2.offsetHeight - d3.offsetHeight - d4.offsetHeight + 15 + "px";
d6.style.top = - d1.offsetHeight - d2.offsetHeight - d3.offsetHeight - d4.offsetHeight - d5.offsetHeight +12.5 + "px";
d5.style.left = d4Loc.right -5+ "px";
d6.style.left = d5Loc.right + d4Loc.right -10 + "px";
If you don't care about old browsers support (doesn't work with IE9 or above) then you can reorder your divs vertically by using the CSS3 column-count Property and setting it to 3 columns :
Add this to #wrapper :
-webkit-column-count: 3;
-webkit-column-fill: auto;
-moz-column-count: 3;
-moz-column-fill: auto;
column-count: 3;
column-fill: auto;
Then replace float:left; in your #wrapper div by display: inline-block;
Here is a CODEPEN DEMO.
NOTE: If browser support and div order are important then an elegant solution may be found in this StackOverFlow post : how to replicate pinterest.com's absolute div stacking layout
you know that there is an actual "css grid" that you can use? It doesn't quite work yet in IE (it does, but only somewhat), but in all other relevant browsers it works well. Basically, you specify gridlines and then place the boxes that you want to within them.
I made a codepen so you can see it in action. (oh, and no javascript needed)
https://codepen.io/quibble/pen/NaKdMo
#wrapper{
display:grid;
grid-gap:10px;
grid-template-columns:50px 50px 50px;
grid-template-rows: 30px 3px 27px 13px 17px 40px; /*the pixels add up to the corresponding bottoms of each grid container. There are a few ways to do this but I like this one.*/
grid-template-areas:
/*This allows you to specify which grid blocks go where. Notice that some are repeated, this just means they span two or more grid areas. For example, box 3 is 33 px so must span one column and two rows (the 30 and 3px one)*/
"one two three"
"one five three"
"one five six"
"four five six"
"four five ."
"four . .";/* the . is for a blank gridspace */
}
#wrapper>div{
background-color:gray;
}
.d_1{
grid-area:one;
}
.d_2{
grid-area:two;
}
.d_3{
grid-area:three;
}
.d_4{
grid-area:four;
}
.d_5{
grid-area:five;
}
.d_6{
grid-area:six;
}
I'm pretty sure this is exactly what you want. You can even mess around with the order of the numbers (in case you want to rearrange your blog posts or pictures) and you can add more pretty easily. You even have "grid-template-areas:" which allows you to specify EXACTLY where each item will go. NO MORE HACKING FOR POSITIONSSS
Good luck out there! Please mark right if this helped.
(P.S., if you need more information on grid, one of the people that pushed for it very heavily (Rachel Andrew) made a tutorial: https://gridbyexample.com/)
This seems similar to another topic: how-create-grid-out-of-images-of-different-sizes
I fully agree with #Quibble on this.
He basically used the layout you wanted. I made a different one, it just has a different approach, though areas are the more elegant way. Just something to bear in mind, you can do it in several ways, none of which involve JS-based coding. My JSfiddle example.
.container {
display: grid;
padding: 60pt;
grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 2fr;
/* there are five values for five columns, each column gets a relative
width in relation to the grid*/
grid-template-rows: 10% 45% 35% 10%;
grid-column-gap: 10px;
grid-row-gap: 5px;
/*this means there are three rows*/
}
.container div img {
width: 100%;
height: 100%;
}
.main_1 {
grid-column: 2/5;
grid-row: 2/3;
}
.main_2 {
grid-column: 5/8;
grid-row: 2/3;
}
.main_3 {
grid-column: 8/11;
grid-row: 2/3;
}
.main_4 {
grid-column: 2/4;
grid-row: 3/4;
}
.main_5 {
grid-column: 4/7;
grid-row: 3/4;
}
.main_6 {
grid-column: 7/11;
grid-row: 3/4;
}
.footer {
grid-row: 4/5;
grid-column: 1/6;
}
Related
I have made up a grid layout that consists of 3 columns wide and 3 rows tall:
.home-works {
padding: 30px;
font-size: 1.2rem;
display: grid;
grid-template-columns: 2fr 2fr 2fr;
grid-template-rows: 2fr 4fr 4fr;
grid-gap: 10px;
}
This is giving me zero problems at desktop view, but what I need to follow up with, now, is when the view port breaks, at the moment I'm working with a max-width:768px rule. So, right now, once the view port breaks to that max-width, any CSS Grid command doesn't seem to have an effect or a change. I have tried using grid-row or grid-row-start grid-column or grid-row-start but no luck.
This is my HTML for the layout:
<div class="home-works">
<div class="head">
<h1>Let's stay connected!</h1>
</div>
<div class="col-menu">
<img class="image-home" src="img/profile-picture.png" width="50%">
<ul>
<li>home</li>
<li>about</li>
<li>contact</li>
<li>downloads</li>
</ul>
</div>
<div class="main-content">
<p>This is my website and I call it, the <em>"glassless window"</em>
Why? Because using the frame on your device (mobile, desktop or laptop)
we are allowed to establish a connection thus enabling me to show you my
up and coming projects. </p>
</div>
<div class="caption-object">
<p>I really wish you could <a class="drop-a-line-link" href="#">drop me a line</a> somewhere
in the future!</p>
</div>
</div>
And this is the CSS for the distribution:
.head {
grid-column: 1 / 4;
text-align: center;
}
.col-menu {
grid-column: 1;
grid-row: 2 / 3;
}
.main-content {
grid-column: 2 / 4;
grid-row: 2 / 3;
}
.caption-object {
grid-column: 3 / 4;
grid-row: 3;
}
This is my first time going about media queries and CSS Grid, meaning this is the first time i input a grid command inside a media query rule set. I checked to see if this would happen too if I wanted to change the background-color: plum; and it did worked. I know about repeat(minmax()) but honestly I wouldn't know how to properly achieve the same look or if it would have the same 'layout design' because then I'd have to delete the grid row's and column's placement? Like I said this is my first time ever using CSS Grid with media queries, I have attached some pics, thanks!
Initially I decided not to include it because nothing had seemed to be working so I didn't have a reason to include.
#media only screen and (max-width: 768px) {
.nav-items {
flex-direction: column;
align-items: center;
}
.navbar {
height: 200px;
padding-bottom: 20px;
}
.footer-link {
align-self: center;
left: 0;
top: 0;
}
.main-container {
flex-flow: column wrap;
margin: 0 10px;
}
.drop-a-line-link {
text-decoration: underline wavy;
}
}
Media Query
To answer my own question this is what I did and its available on MDN, have to check "Redefining the grid using media queries" topic.
To reorganize a CSS Grid layout one must set up the media query rule (which in this case I had it different than on MDN archives but somehow still worked) and in there I had to reassign my grid-template-areas, which was also another thing I lacked, I was NOT using grid-areas, I had stuff like grid-row or grid-columns. Apparently this seems to be a huge factor that comes to play when we are inside our Media Query code. One thing that they do note as important, when working with grid-areas is that one should assign them, outside of any Media Query commands, to cover just one "row" or one "column", I guess depends on your current grid-auto-flow command, which at default is set as row while defining the columns and rows
So, mine is looking like this:
display: grid;
grid-template-columns: 1fr;
grid-template-rows: minmax(350px, auto);
grid-template-areas:
"header"
"menu"
"main"
"caption";
Since I had not defined any areas on my previous grid I would never have gotten it to work the way I intended for it to behave. Well, and then once in the MQ, you assign the grid as best you can, but first, you need to use grid-template-areas to re-assign the areas, and as well as your columns, using grid-template-columns, this depends on your layout and item sizes or basically it depends on the idea that you had for the grid.
So my Media Query code ended up looking like this:
#media (min-width: 500px) {
.home-works {
grid-template-columns: 2fr 2fr 2fr;
grid-template-areas:
"header header menu"
". main main"
". . caption";
}
}
#media (min-width:700px) {
.home-works {
grid-template-areas:
"header header header"
"menu main main"
". . caption";
}
}
Important: the "." are "white-space", or "negative space" or "empty cells".
I'm trying to make a grid that has a full span row at the bottom.
For full span columns I can use grid-column: 1/-1.
For single span columns I can use grid-column: 1/1.
For single span rows I can use grid-row: 1/1.
But if I want to define the last column or row, I have to write grid-column: -2/-1.
Why is the syntax not the same as with 1/1 for the first column/row? Or am I making a mistake somewhere?
I also made a jsfiddle to demonstrate my problem: jsfiddle
.grid-container {
display: grid;
grid-template-columns: 5px 1fr 1fr;
grid-template-rows: minmax(50px, 2fr) 1fr 1fr 1fr 1fr 1fr 15px;
}
.grid-item {
width: 1fr;
}
.header {
display: flex;
grid-column: 2/-1;
grid-row: 1/1;
justify-content: center;
}
.border-left {
background: purple;
grid-column: 1/1;
grid-row: 1/-1;
}
.border-bottom {
background: #410266;
grid-column: 2/-1;
/* grid-row: -2 / -1; this will work, -1/-1 will not */
grid-row: -1 / -1;
}
<div class="grid-container">
<div class="header"> HEADER </div>
<div class="border-left"></div>
<div class="grid-item">1 </div>
<div class="grid-item">2 </div>
<div class="grid-item">3 </div>
<div class="grid-item">4 </div>
<div class="border-bottom"></div>
</div>
The grid-column and grid-row shorthand properties count grid lines.
You wrote:
For single span columns I can use grid-column: 1/1
This doesn't make any sense. It resolves to:
grid-column-start: 1
grid-column-end: 1
So you're defining a column that goes from the starting line to the starting line.
A column has a starting line and an ending line. So to span the first column you use:
grid-column: 1 / 2
The only reason your code works as you expect is because the Grid error handling algorithm removes the end line when the start and end lines are equal.
So 1 / 1 resolves to 1 / auto, where auto represents a default span of 1.
You wrote:
But if I want to define the last column or row, I have to write grid-column: -2/-1
Yes, that's one way to do it. (You can also use positive integers, since you know the number of columns.)
You wrote:
Why is the syntax not the same as with 1/1 for the first column/row? Or am I making a mistake somewhere?
1 / 1
As mentioned above, 1/1 was invalid. It is fixed by the Grid system, resolving to 1 / auto. As a result, you span the first column.
-1 / -1
This combination of values is also invalid. It means span from the last line of the grid to the last line of the grid. Grid error handling changes the end value to -1 / auto. This takes you out of the explicit grid (because an implicit column is created) and negative values no longer apply. The negative values end where the implicit grid begins (demo).
-2 / -1
Correct syntax. So it works. Span one column starting from the penultimate line of the grid.
when using the same value inside grid-column/grid-row you will fall into this rule:
If the placement for a grid item contains two lines, and the start line is further end-ward than the end line, swap the two lines. If the start line is equal to the end line, remove the end line.ref
So saying grid-column:-1/-1 means grid-column:-1 which is grid-column:-1/auto
auto
The property contributes nothing to the grid item’s placement, indicating auto-placement or a default span of one. (See § 8 Placing Grid Items, above.)
So basiclly you said to your element to start at the last line and span one column which will create an implicit new column:
A basic example to illustrate:
.box {
display:grid;
grid-template-columns:20px 20px 20px;
grid-auto-columns:100px;
grid-gap:5px;
}
span {
grid-column:-1/-1;
height:40px;
background:red;
}
<div class="box">
<span></span>
</div>
You can see that the span is having 100px which means it create a new column inside the implicit grid and is not inside the explicit one defined by 20px
When using -2/-1 it's clear that you will consider the before the last and the last line and the element will be placed in the last explicit column:
.box {
display:grid;
grid-template-columns:20px 20px 20px;
grid-auto-columns:100px;
grid-gap:5px;
}
span {
grid-column:-2/-1;
height:40px;
background:red;
}
<div class="box">
<span></span>
</div>
Same logic apply when using positive value but you won't notice a strange behavior since you will most likely span an explicit column thinking it's correct to specify, for example, grid-column:1/1
I'm trying to solve a grid problem with how the elements are automatically placed in the rows not in the way I intend them to. The code is the simplest possible variation written to demonstrate the issue. The number of paragraphs is variable-length, there can be any amount of them.
div {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
p:nth-child(4n + 1) {
grid-column: 1 / span 1;
}
p:nth-child(4n + 2) {
grid-column: 2 / span 1;
}
p:nth-child(4n + 3) {
grid-column: 2 / span 1;
}
p:nth-child(4n) {
grid-column: 1 / span 1;
}
<div>
<p>Test1</p>
<p>Test2</p>
<p>Test3</p>
<p>Test4</p>
<p>Test5</p>
<p>Test6</p>
<p>Test7</p>
<p>Test8</p>
<p>Test9</p>
<p>Test10</p>
</div>
Here is the current result, with two arrows showing what I want to achieve:
And here is exactly what I want to achieve, created for presentation purposes by just reordering HTML elements in a basic grid:
Thank you in advance!
This can be solved with the grid-auto-flow: dense CSS rule on the grid parent. This has the effect that previously blank cells will be filled, rather than searching for the next available space.
I have partially stacked two images using CSS Grid. The image that the user hovers over increases in z-index and therefore overlays the other. Users can switch back and forth between those two images.
Now I am wondering if it's possible to give the image that it is currently in "focus"/has the higher z-index a box-shadow that appears/disappears, depending which image is on top. Is that even possible using CSS only?
Example of what I mean. And the grey layer seems to have a shadow.
http://vrscigroup.com
You can't achieve this with CSS only, you need something that tells CSS which is the card with the higher z-index, after that you can apply a class.
I would add something with js (jquery maybe?) that adds a class and use that class to add the box shadow, something like this:
$('.cards').hover(function() {
// remove it from all cards
$('.cards').removeClass('box-shadow');
// add it to the one on hover only
$(this).addClass('box-shadow');
});
After that just add the css class:
.cards.box-shadow {
box-shadow: 0 0 20px #000;
}
Of course, that's just an example :)
Use :hover pseudoclass here instead of JavaScript. Demo:
.grid {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
}
/* overlapping grid items */
.item-1 {
grid-row: 1 / 3;
grid-column: 1 / 3;
background-color: green;
}
.item-2 {
grid-row: 2 / 4;
grid-column: 2 / 4;
background-color: yellow;
}
/* setting higher z-index on hover */
.item-1:hover {
z-index: 1;
}
/* adding box shadow */
.item:hover {
box-shadow: 0 0 10px #000;
}
<div class="grid">
<div class="item item-1"></div>
<div class="item item-2"></div>
</div>
I'm using following HTML markup for my grid.
<section class="grid">
<article class="grid-item width-2x height-2x">....</article>
<article class="grid-item">....</article>
<article class="grid-item">....</article>
<article class="grid-item width-2x">....</article>
<article class="grid-item height-2x">....</article>
<article class="grid-item">....</article>
<article class="grid-item">....</article>
<article class="grid-item width-2x height-2x">....</article>
</section>
The SCSS code is something like below:
.grid {
display: grid;
grid-template-columns: repeat( 4, 1fr );
grid-gap: 30px;
align-items: start;
.grid-item {
&.height-2x {
grid-row: span 2;
}
&.width-2x {
grid-column: span 2;
}
}
}
Since I'm using auto-prefixer in my workflow it automatically adds all relevant properties with -ms prefix. I can confirm it via inspect element.
Now, the issue is this code works just fine in Chrome, Firefox and Opera, but when I open this page in Microsoft Edge or in IE 11 all grid items are overlapping each other at first cell. According to this site these browsers support CSS Grid layout with -ms prefix. I've created a CodePen for this scenario.
CodePen Link
Why is it not working?
.grid {
display: -ms-grid;
display: grid;
-ms-grid-columns: (1fr)[4];
grid-template-columns: repeat(4, 1fr);
-ms-grid-rows: (270px)[4];
grid-template-rows: repeat(4, 270px);
grid-gap: 30px;
}
.grid .grid-item {
background-color: #000;
color: #fff;
text-align: center;
line-height: 270px;
}
.grid .grid-item.height-2x {
-ms-grid-row: span 2;
grid-row: span 2;
}
.grid .grid-item.width-2x {
-ms-grid-column: span 2;
grid-column: span 2;
}
<section class="grid">
<article class="grid-item width-2x height-2x">....</article>
<article class="grid-item">....</article>
<article class="grid-item">....</article>
<article class="grid-item width-2x">....</article>
<article class="grid-item height-2x">....</article>
<article class="grid-item">....</article>
<article class="grid-item">....</article>
<article class="grid-item width-2x height-2x">....</article>
</section>
IE11 uses an older version of the Grid specification.
The properties you are using don't exist in the older grid spec. Using prefixes makes no difference.
Here are three problems I see right off the bat.
repeat()
The repeat() function doesn't exist in the older spec, so it isn't supported by IE11.
You need to use the correct syntax, which is covered in another answer to this post, or declare all row and column lengths.
Instead of:
.grid {
display: -ms-grid;
display: grid;
-ms-grid-columns: repeat( 4, 1fr );
grid-template-columns: repeat( 4, 1fr );
-ms-grid-rows: repeat( 4, 270px );
grid-template-rows: repeat( 4, 270px );
grid-gap: 30px;
}
Use:
.grid {
display: -ms-grid;
display: grid;
-ms-grid-columns: 1fr 1fr 1fr 1fr; /* adjusted */
grid-template-columns: repeat( 4, 1fr );
-ms-grid-rows: 270px 270px 270px 270px; /* adjusted */
grid-template-rows: repeat( 4, 270px );
grid-gap: 30px;
}
Older spec reference:
https://www.w3.org/TR/2011/WD-css3-grid-layout-20110407/#grid-repeating-columns-and-rows
span
The span keyword doesn't exist in the older spec, so it isn't supported by IE11. You'll have to use the equivalent properties for these browsers.
Instead of:
.grid .grid-item.height-2x {
-ms-grid-row: span 2;
grid-row: span 2;
}
.grid .grid-item.width-2x {
-ms-grid-column: span 2;
grid-column: span 2;
}
Use:
.grid .grid-item.height-2x {
-ms-grid-row-span: 2; /* adjusted */
grid-row: span 2;
}
.grid .grid-item.width-2x {
-ms-grid-column-span: 2; /* adjusted */
grid-column: span 2;
}
Older spec reference:
https://www.w3.org/TR/2011/WD-css3-grid-layout-20110407/#grid-row-span-and-grid-column-span
grid-gap
The grid-gap property, as well as its long-hand forms grid-column-gap and grid-row-gap, don't exist in the older spec, so they aren't supported by IE11. You'll have to find another way to separate the boxes. I haven't read the entire older spec, so there may be a method. Otherwise, try margins.
grid item auto placement
There was some discussion in the old spec about grid item auto placement, but the feature was never implemented in IE11. (Auto placement of grid items is now standard in current browsers).
So unless you specifically define the placement of grid items, they will stack in cell 1,1.
Use the -ms-grid-row and -ms-grid-column properties.
CSS Grid auto placement in IE/EDGE
CSS Grid not working in ie11 despite prefixes
https://www.w3.org/TR/2011/WD-css3-grid-layout-20110407/#automatic-placement-of-grid-items
Michael has given a very comprehensive answer, but I'd like to point out a few things which you can still do to be able to use grids in IE in a nearly painless way.
The repeat functionality is supported
You can still use the repeat functionality, it's just hiding behind a different syntax. Instead of writing repeat(4, 1fr), you have to write (1fr)[4]. That's it.
See this series of articles for the current state of affairs: https://css-tricks.com/css-grid-in-ie-debunking-common-ie-grid-misconceptions/
Supporting grid-gap
Grid gaps are supported in all browsers except IE. So you can use the #supports at-rule to set the grid-gaps conditionally for all new browsers:
Example:
.grid {
display: grid;
}
.item {
margin-right: 1rem;
margin-bottom: 1rem;
}
#supports (grid-gap: 1rem) {
.grid {
grid-gap: 1rem;
}
.item {
margin-right: 0;
margin-bottom: 0;
}
}
It's a little verbose, but on the plus side, you don't have to give up grids altogether just to support IE.
Use Autoprefixer
I can't stress this enough - half the pain of grids is solved just be using autoprefixer in your build step. Write your CSS in a standards-complaint way, and just let autoprefixer do it's job transforming all older spec properties automatically. When you decide you don't want to support IE, just change one line in the browserlist config and you'll have removed all IE-specific code from your built files.
The answer has been given by Faisal Khurshid and Michael_B already.
This is just an attempt to make a possible solution more obvious.
For IE11 and below you need to enable grid's older specification in the parent div e.g. body or like here "grid" like so:
.grid-parent{display:-ms-grid;}
then define the amount and width of the columns and rows like e.g. so:
.grid-parent{
-ms-grid-columns: 1fr 3fr;
-ms-grid-rows: 4fr;
}
finally you need to explicitly tell the browser where your element (item) should be placed in e.g. like so:
.grid-item-1{
-ms-grid-column: 1;
-ms-grid-row: 1;
}
.grid-item-2{
-ms-grid-column: 2;
-ms-grid-row: 1;
}
To support IE11 with auto-placement, I converted grid to table layout every time I used the grid layout in 1 dimension only. I also used margin instead of grid-gap.
The result is the same, see how you can do it here https://jsfiddle.net/hp95z6v1/3/