CSS grid elements not aligned properly - css

seems like an easy task which Im trying to get done since hours. I cant get my grid elements vertical aligned properly. Please take a look at the fiddle to get the idea. Maybe someone could help me with this issue.
HTML
<section class="top">
<div></div>
<div></div>
</section>
<section class="bottom">
<div></div>
<div></div>
<div></div>
</section>
CSS
section {
display: grid;
grid-template-rows:auto;
margin: 40px 0 0 0
}
section.top {
grid-template-columns:2fr 1fr;
grid-column-gap: 50px;
}
section.bottom {
grid-template-columns:1fr 1fr 1fr;
grid-column-gap: 50px;
}
section div {
background:lightblue;
height:400px
}
https://jsfiddle.net/ecj1wrae/

Well, with some thinking and calculation this one here does the trick
CSS
section.top {
grid-template-columns:calc(66% + 2vw) 34%;
grid-column-gap: 2vw;
}
section.bottom {
grid-template-columns:33% 33% 34%;
grid-column-gap: 2vw;
}
https://jsfiddle.net/ecj1wrae/3/

I know this is an old question... But I had a similar problem and I thought I'd share my solution for anyone else that needs some help.
This comment helped push me in the right direction
But you're dividing space using fr units, which applies only free
space in the container. And the bottom section has 50px less free
space than the top. So they cannot be aligned in this manner
As the layout needs to consider the gaps between the columns I found it better to frame the problem as it needs to take up 2 columns of a 3 column layout instead of thinking it needs to take up 2fr of a 3fr layout.
Helpfully grid allows us to specify how many columns an element can span grid-column: span 2;
Using the html in the question we can use a span on the first div in the top section:
section {
display: grid;
margin: 40px 0 0 0;
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-column-gap: 50px;
}
section.top div:first-child {
grid-column: span 2;
}

If you would like to do it with only 1 parent element, this may be a solution:
.wrapper {
display: grid;
grid-template-columns: auto auto auto auto;
grid-row-gap: 50px;
grid-column-gap: 10px;
grid-template-areas:
'item1 item1 item1 item1 item2'
'item3 item3 item4 item4 item5';
}
.wrapper > div {
background: red;
height: 400px;
}
.item1 {
grid-area: item1;
}
.item2 {
grid-area: item2;
}
.item3 {
grid-area: item3;
}
.item4 {
grid-area: item4;
}
.item5 {
grid-area: item5;
}
<div class="wrapper">
<div class="item1"></div>
<div class="item2"></div>
<div class="item3"></div>
<div class="item4"></div>
<div class="item5"></div>
</div>

A really simple solution is change the grid-column-gap by margin (if having space on the sides is not a problem):
HTML
<section class="top">
<div></div>
<div></div>
</section>
<section class="bottom">
<div></div>
<div></div>
<div></div>
</section>
CSS
section {
display: grid;
grid-template-rows:auto;
margin: 4px 0 0 0
}
section.top {
grid-template-columns:2fr 1fr;
}
section.bottom {
grid-template-columns:1fr 1fr 1fr;
}
section div {
background:lightblue;
height:400px;
margin: 5px;
}
https://codepen.io/fillsanches/pen/oNEpKWN

Related

CSS fr / fractional units minimum too large

I have a jsfiddle.
What I have:
What I want:
Problem:
The hopefully relevant section is:
grid-template-columns: repeat(auto-fit, 1fr);
where both elements in my section have width: max-content;.
This (and the expanded but technically identical form of repeat(auto-fit, minmax(auto, 1fr));) do not do what I expect - it creates picture 1, I expect it to look like picture 2. It looks like the minimum width for these elements is too large, so instead of being on one row, it puts them in columns.
I made picture 2 by changing the code to repeat(auto-fit, minmax(200px, 1fr));. This is not a great solution as I want the minimum element size to be based on the grid elements' widths, not some arbitrary value.
I do want to have the elements able to be on different rows (for instance, if the browser is very narrow), so CSS grid seems useful for this task. I'm obviously just misunderstanding some key aspect.
Question
What value can I use in my grid-template-columns to make my elements work the way I expect with CSS grid? Is there a way to do it with repeat(auto-fit, X); or do I have to specify the number?
Answer
As stated below, you cannot use repeat(auto-fit with fr as it does not specify an absolute minimum or maximum, which the spec says is invalid.
Michael_B gave the answer (in his jdfiddle example comment) of using
display: flex;
flex-wrap: wrap;
which does exactly what I expected repeat(auto-fit, 1fr); to do.
This rule won't work.
grid-template-columns: repeat(auto-fit, 1fr)
The problem is explained here: minmax fails (invalid property value)
This rule won't work:
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))
The problem is explained here: minmax() defaulting to max
You can use min-content
.page-container {
display: grid;
grid-gap: 0.5rem;
grid-template-columns: 20% 80%;
grid-template-rows: auto auto 20rem;
grid-template-areas: "header header" "sidebar content" "footer footer";
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 25px;
padding: 50px;
}
.header {
grid-area: header;
display: grid;
grid-template-columns: repeat(2, min-content);
grid-gap: 10px;
}
.header>* {
background-color: lightgreen;
}
.header a:link {
color: inherit;
text-decoration: none;
}
.header a:hover {
/* https://html.spec.whatwg.org/multipage/rendering.html#phrasing-content-3 */
text-decoration: underline;
}
.header h1,
h2 {
margin: 0;
width: max-content;
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
.footer {
grid-area: footer;
}
<div class="page-container">
<section class="box header">
<h1><a href="https://jeremy.richards.dev">
Jeremy.Richards.dev
</a></h1>
<h2>
and this on the
</h2>
</section>
<div class="box sidebar">
Sidebar
</div>
<div class="box content">
Content
</div>
<div class="box footer">
<h2 style="font-size: 2rem;">
Something
</h2>
<h3 style="font-size: 1.5rem;">
My name underneath
</h3>
<p>
Linkedin/github/SO
</p>
</div>
</div>

How to collapse the width of CSS-grid to center it in the grid-container

Is it possible to collapse the width of a CSS grid with auto-filled columns to the minimal width required to have equal width columns that are centered with respect to the grid container?
IE if I have grid defined like this:
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
and the grid-container is 800px wide, is there a way to ensure the grid itself is only 600px wide instead of 800px?
Since I'm not sure how to explain it properly I've made a fiddle: https://jsfiddle.net/mhozx4ns/10/
I'm looking for a way that makes the top container behave like the bottom one if it is wider than what is required to place all children in one row.
body {
width: 800px;
background: black;
}
.grid div {
height: 50px;
background: #ededed;
}
.css {
display: grid;
justify-content: center;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-column-gap: 64px;
grid-row-gap: 64px;
background: red;
}
.manual {
width: 664px;
margin: 32px auto 0;
background: blue;
}
.manual:after {
content: '';
display: table;
width: 100%;
}
.manual.grid div {
width: 300px;
float: left;
margin-bottom: 64px;
}
.manual.grid div:nth-of-type(even) {
margin-left: 64px;
}
.manual.grid div:last-child {
margin-bottom: 0;
}
}
<div class="css grid">
<div>
</div>
<div>
</div>
<div>
</div>
</div>
<div class="manual grid">
<div>
</div>
<div>
</div>
<div>
</div>
</div>
When you say minmax(300px, 1fr) in your rule, you're saying this:
Each column must be a minimum width of 300px and a maximum width of 1fr.
The fr unit consumes free space in the grid container. So if your container is 800px wide, the fr will factor in all that space.
Also, since fr consumes all free space, justify-content, which functions by distributing free space, is rendered useless.
Why not just remove the 1fr?
body {
width: 800px;
background: black;
}
.css {
display: grid;
justify-content: center;
grid-template-columns: repeat(auto-fill, 300px);
grid-auto-rows: 50px;
grid-column-gap: 64px;
grid-row-gap: 64px;
background: red;
}
.grid div {
background: #ededed;
}
<div class="css grid">
<div></div>
<div></div>
<div></div>
</div>

Nested CSS grid

I'm currently working on a CSS grid layout where I want two divs in a container to be 50% width each. But I cant really figure out how.
The element nav has two divs inside it which I want to be 50% each, but using the grid-syntax. How would you do that?
Code:
$gutter: 30px;
$columns: 12;
$maxwidth: 1200px;
#container {
max-width: $maxwidth;
width: 100%;
margin: 0 auto;
display: grid;
grid-template-columns: repeat($columns, 1fr);
grid-column-gap: $gutter;
grid-template-areas: "nav" "header" "main" "footer";
}
header, nav, main, footer {
grid-column: span $columns;
}
Markup:
<div id="container">
<nav>
<div></div>
<div></div>
</nav
<header></header>
<main></main>
<footer></footer>
</div>
image:
You can simply use like this
nav {
display: grid;
grid-template-columns: 1fr 1fr;
}
nav div {
background: red;
height: 250px;
}
nav div + div {
background: green;
}
<div id="container">
<nav>
<div></div>
<div></div>
</nav>
<header></header>
<main></main>
<footer></footer>
</div>
To know more about GRID
nav {
display: grid;
grid-template-columns: repeat(2, 1fr);
}

Overlapping grid items using grid-template-areas / named areas

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>

Image width exceeds container width when using CSS grid feature

I'm currently working on some layout and I have an issue with image width exceeding the container width when applying CSS grid rules.
Please, take a look at the code below.
img {
max-width: 100%;
height: auto;
display: block;
}
.page {
display: grid;
grid-template-columns: auto minmax(300px, 400px);
grid-column-gap: 1rem;
height: 100vh;
}
.content {
grid-column: 1 / 2;
background: red;
width: 100%;
}
.sidebar {
grid-column: 3;
background: lime;
}
<div class="page">
<div class="content">
<img src="http://via.placeholder.com/900x400" alt="" width="900" height="400">
<p>content</p>
</div>
<div class="sidebar">
<p>sidebar</p>
</div>
</div>
I'm wondering what might cause that issue. The sidebar has to be between 300px and 400px. The content container should take the rest.
For some reason, the image is breaking this layout setup.
https://codepen.io/sunpietro/pen/ZyNgqe
Fixed grid-template-columns. It should be grid-template-columns: auto 1fr minmax(300px, 400px). auto for image, 1fr for content, and minmax(300px, 400px) forsidebar` (it resides in 3rd column). Demo:
img {
max-width: 100%;
height: auto;
display: block;
}
.page {
display: grid;
grid-template-columns: auto 1fr minmax(300px, 400px);
grid-column-gap: 1rem;
height: 100vh;
}
.content {
grid-column: 1 / 2;
background: red;
width: 100%;
}
.sidebar {
grid-column: 3;
background: lime;
}
<div class="page">
<div class="content">
<img src="http://via.placeholder.com/900x400" alt="" width="900" height="400">
<p>content</p>
</div>
<div class="sidebar">
<p>sidebar</p>
</div>
</div>
You have a two-column grid.
grid-template-columns: auto minmax(300px, 400px);
This means there are three grid column lines: 1, 2 and 3.
The image is nested in a grid item which occupies the first column:
.content {
grid-column: 1 / 2;
}
But you have the sidebar skipping the second column and starting at grid column line 3 (the end of the explicit grid):
.sidebar {
grid-column: 3;
}
This breaks down to:
grid-column-start: 3;
grid-column-end: auto;
So there's nothing in the second column.
Try this instead:
.sidebar {
grid-column: 2 / 3;
}
revised codepen

Resources