I'm learning CSS grid and while trying to do my layout and use semantic html at the same time I run into some problems
https://codepen.io/oscarryz/pen/oNNBKyd
So basically I'm doing grid as 3x3 with empty space on the left and right and the content in the middle
.grid-container {
display: grid;
grid-template-columns: 1fr 40em 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas:
" . header . "
" . content . "
" . footer . ";
}
.header {
grid-area: header;
}
.content {
grid-area: content;
}
.footer {
grid-area: footer;
}
.header, .content, .footer {
border: 1px solid red;
}
<div class="grid-container">
<header>
<div class="header">header</div>
</header>
<main>
<div class="content">content</div>
</main>
<footer>
<div class="footer">footer</div>
</footer>
</div>
As can be seen in the codepen above, this is not working. If I remove the semantic tags it works, obviously there must be a correct way of doing this
Grid templates are for direct descendants.
The semantic elements should be referenced by tagname, not class:
/* changed from .header, which is a _child_ of header */
header {
grid-area: header;
}
/* changed from .content, which is a _child_ of main */
main {
grid-area: content;
}
/* changed from .footer, which is a _child_ of footer */
footer {
grid-area: footer;
}
Corrected codepen here: https://codepen.io/c_bergh/pen/eYYvOmG
You've assigned grid areas to your non-semantic elements in your CSS. That's why the semantic elements are interfering with your grid — because they ended up not participating in your grid at all. If you had started out with the non-semantic structure, then migrated to semantic elements, this may have been a step you missed.
Assigning the grid areas to your semantic elements allows you to remove the non-semantic ones instead, completing this migration:
html,
body,
.grid-container {
height: 100%;
margin: 0;
}
.grid-container * {
border: 1px solid red;
position: relative;
}
.grid-container {
display: grid;
grid-template-columns: 1fr 40em 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas:
" . header . "
" . content . "
" . footer . ";
}
header {
grid-area: header;
}
main {
grid-area: content;
}
footer {
grid-area: footer;
}
<div class="grid-container">
<header>header</header>
<main>content</main>
<footer>footer</footer>
</div>
Related
So I'm trying to set up a grid-formatted website page with pure HTML and CSS, as you will see in my code below.
I'm trying to alternate between two div tags going down the left hand column of Header & inner-placeholder tags.
You will see the HTML layout alignment with the grid-template-area clearly laid out, along with the number of rows as specified by grid-template-rows
So why do I get just a red box at the corner of the screen when it's fairly obvious what I want to have as per the illustration - except for a curved box followed by a straight box, followed by a curved box etc going down the left hand side?
I have tried to change the fr number to accommodate the number of rows on the left hand side.
Thank you.
Illustration
.grid{
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-areas:
"Title Title"
"Header Content"
"inner-placeholder Content"
"Header Content"
"inner-placeholder Content"
"Sidebar Content"
"Footer Footer";
grid-gap: 10px;
}
.Title{
grid-area: Title;
}
.Header{
grid-area: Header;
}
.Sidebar{
grid-area: Sidebar;
}
.Content{
grid-area: Content;
}
.Footer{
grid-area: Footer;
}
.inner-placeholder{
grid-area: inner-placeholder;
}
.grid div:nth-child(even){
background-color: red;
}
.grid div:nth-child(odd){
background-color: green;
}
<div class="grid">
<div class="Title">Title
</div>
<div class="Header">Header
</div>
<div class="inner-placeholder">
</div>
<div class="Header">Header
</div>
<div class="inner-placeholder">
</div>
<div class="Sidebar">Sidebar
</div>
<div class="Content">Content
</div>
<div class="Footer">Footer
</div>
</div>
It seems you misunderstood how grid areas work. If any grid area spans more than 1 row or column, it needs to form a square or a rectangle. Which means they also need to be in one continuous sequence as a 2x2 or 1x3 and so on, in your case you split the Header area and placeholder area between each other, which breaks the grid.
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(7, 1fr);
grid-template-areas:
"Title Title"
"Header Content"
"inner-placeholder Content"
"Header2 Content"
"inner-placeholder2 Content"
"Sidebar Content"
"Footer Footer";
grid-gap: 10px;
}
.Title {
grid-area: Title;
}
.Header {
grid-area: Header;
}
.Header2 {
grid-area: Header2;
}
.Sidebar {
grid-area: Sidebar;
}
.Content {
grid-area: Content;
}
.Footer {
grid-area: Footer;
}
.inner-placeholder {
grid-area: inner-placeholder;
}
.inner-placeholder2 {
grid-area: inner-placeholder2;
}
.grid div:nth-child(even) {
background-color: red;
}
.grid div:nth-child(odd) {
background-color: green;
}
<div class="grid">
<div class="Title">Title</div>
<div class="Header">Header</div>
<div class="inner-placeholder"></div>
<div class="Header2">Header2</div>
<div class="inner-placeholder2"></div>
<div class="Sidebar">Sidebar</div>
<div class="Content">Content</div>
<div class="Footer">Footer</div>
</div>
I'm laying out HTML for a project, and as you can see on the joined picture, I have an issue about properly implementing <main> tag.
My layout has a content header above the sidebar and content, which prevents me from keeping the sidebar outside the main tag.
Would someone have a solution?
I tried having the sidebar code below the content in the HTML structure, and display it as shown in the picture with flexbox reverse row, but as soon as I wrap what I want inside a <main> semantic tag, everything breaks.
Use display: contents; to stop the main element having any effect on layout. Then layout its children as if they were siblings of main instead of children of it.
body {
background: black;
display: grid;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas: "header header header" "content-header content-header content-header" "sidebar content content";
margin: 0;
padding: 0;
height: 100vh;
}
header {
background: #aaf;
grid-area: header;
}
main {
display: contents;
}
main header {
background: #faa;
grid-area: content-header;
}
main #content {
background: #afa;
grid-area: content;
}
aside {
background: #aff;
grid-area: sidebar;
}
<header>
header
</header>
<main>
<header>
content header
</header>
<div id="content">
content
</div>
</main>
<aside>
sidebar
</aside>
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I'm not understanding why the footer is not filling the entire bottom of the screen. Note: if I try to extend aside into that corner instead of footer it will also leave that are blank. Just refuses to fill that area with content. My project consists only of the css and html I have shown here. It behaves the same in chrome.
HTML:
<body>
<div class="container">
<header> header</header>
<main>main</main>
<aside>aside</aside>
<footer>footer</footer>
</div>
</body>
CSS:
.container {
height: 100vh;
display: grid;
grid-template-columns: 2fr 1fr;
grid-template-rows: 100px 100px 100px;
grid-gap: 10px;
grid-template-areas: "header header" "main aside" "footer footer";
}
header {
grid-area: header;
background-color: teal;
}
main {
grid-area: main;
background-color: lightblue;
}
aside {
grid-area aside;
background-color: green;
}
footer {
grid-area footer;
background-color: gray;
}
Result:
firefox
firefox css grid prop
You forgot the colon in your css. It should be grid-area: footer; except you had grid-area footer;. It's fixed now in the snippet below for you. You did the same thing for aside as well. I fixed that in the snippet for you.
.container {
height: 100vh;
display: grid;
grid-template-columns: 2fr 1fr;
grid-template-rows: 100px 100px 100px;
grid-gap: 10px;
grid-template-areas: "header header" "main aside" "footer footer";
}
header {
grid-area: header;
background-color: teal;
}
main {
grid-area: main;
background-color: lightblue;
}
aside {
grid-area: aside;
background-color: green;
}
footer {
grid-area: footer;
background-color: gray;
}
<body>
<div class="container">
<header> header</header>
<main>main</main>
<aside>aside</aside>
<footer>footer</footer>
</div>
</body>
I'm tinkering with CSS Grid and was wondering if it's possible to have nested grids move out of their parent grids when resizing the screen.
I've tried changing the grid-template-areas to include "subcontent" but this seems to be wrong and disrupts the grid.
As an example, I've set up the following template and would like the "subcontent" divs (pink) to replace the "profile" area when the media breakpoint is hit.
Is there any way to do this in pure CSS Grid without roping in JS?
.wrapper {
margin: auto;
width: 80%;
background-color: #e0e0e0;
display: grid;
grid-template-columns: 3fr 1fr;
grid-template-rows: 2fr 1fr 4fr;
grid-template-areas:
" title profile"
" infobar infobar "
" maincontent sidebar ";
grid-gap: 1em;
}
.space {
background-color: #eeeeee;
grid-area: space;
}
.title {
grid-area: title;
background-color: red;
}
.profile {
grid-area: profile;
background-color: orange;
}
.infobar {
grid-area: infobar;
background-color: yellow;
}
.maincontent {
grid-area: maincontent;
display: grid;
grid-template-columns: 2fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas:
"subcontent1 subcontent2"
"subcontent1 subcontent2";
background-color: green;
}
.subcontent1 {
grid-area: subcontent1;
background-color: pink;
margin: 10px;
}
.subcontent2 {
grid-area: subcontent2;
background-color: pink;
margin: 10px;
}
.sidebar {
grid-area: sidebar;
background-color: blue;
}
#media screen and (max-width: 900px) {
.wrapper {
grid-template-columns: 2fr 1fr 1fr;
grid-template-areas:
"title title sidebar"
"infobar infobar infobar"
"profile maincontent maincontent"
"footer footer sidebar"
;
}
.maincontent{
display: block;
}
.subcontent {
grid-area: subcontent;
}
}
<div class="wrapper">
<div class="title">Title</div>
<div class="profile">Profile</div>
<div class="infobar">Info Bar</div>
<div class="maincontent">Main Content
<div class="subcontent1">Main1</div>
<div class="subcontent2">Main2</div>
</div>
<div class="sidebar">Sidebar</div>
</div>
I'm tinkering with CSS Grid and was wondering if it's possible to have nested grids move out of their parent grids when resizing the screen.
Just like you can't extract nested flex containers so they can participate as flex items of an ancestor flex container, you can't extract nested grids to do the same thing.
You would have to make subcontent1 and subcontent2 siblings of the other grid items in your layout to re-position them.
I've tried changing the grid-template-areas to include "subcontent" but this seems to be wrong and disrupts the grid.
There's a good reason for this disruption. You've posted invalid string values.
This is good:
grid-template-areas: " title profile"
" infobar infobar "
" maincontent sidebar "
This is good, as well:
grid-template-areas: "subcontent1 subcontent2"
"subcontent1 subcontent2"
This is bad:
grid-template-areas: "title title sidebar"
"infobar infobar infobar"
"profile maincontent maincontent"
"footer footer sidebar"
Your last declaration is invalid.
String values of the grid-template-areas property must form rectangular blocks. Since sidebar appears twice in a disconnected manner, the entire layout breaks.
In contrast, try these out instead:
grid-template-areas: "title title sidebar"
"infobar infobar infobar"
"profile maincontent maincontent"
"footer footer footer"
jsFiddle demo
OR
grid-template-areas: "title title sidebar"
"infobar infobar infobar"
"profile maincontent maincontent"
"footer footer ..."
jsFiddle demo
Now the layout works. However, there's actually no footer in your HTML, so nothing will render. Regardless, the presence of an invalid string was breaking the layout.
Here are more complete explanations:
grid-template-areas with ASCII art is not working
Grid areas not laying out properly in CSS Grid
I want to make my website using CSS grid system but it seems not to be working. Here is my code:
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "logo faq" "about-us";
}
.logo {
background-color: blue;
grid-area: logo;
}
.faq {
background-color: red;
grid-area: faq;
}
.aboutUs {
background-color: cyan;
grid-area: about-us;
}
<div class="grid">
<div class="logo">
LOGO
</div>
<div class="faq">
FAq
</div>
<div class="aboutUs">
About-us
</div>
</div>
When using the grid-template-areas property, string values must have the same number of columns.
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "logo faq" "about-us about-us";
}
.logo {
background-color: blue;
grid-area: logo;
}
.faq {
background-color: red;
grid-area: faq;
}
.aboutUs {
background-color: cyan;
grid-area: about-us;
}
<div class="grid">
<div class="logo">
LOGO
</div>
<div class="faq">
FAq
</div>
<div class="aboutUs">
About-us
</div>
</div>
You can use a period, or an unbroken line of periods, to represent an empty cell (spec reference).
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "logo faq" " ... about-us";
}
.logo {
background-color: blue;
grid-area: logo;
}
.faq {
background-color: red;
grid-area: faq;
}
.aboutUs {
background-color: cyan;
grid-area: about-us;
}
<div class="grid">
<div class="logo">
LOGO
</div>
<div class="faq">
FAq
</div>
<div class="aboutUs">
About-us
</div>
</div>
From the Grid spec:
7.3. Named Areas: the grid-template-areas
property
All strings must have the same number of columns, or else the declaration is invalid.
If a named grid area spans multiple grid cells, but those cells do not form a single filled-in rectangle, the declaration is invalid.
Non-rectangular or disconnected regions may be permitted in a future version of this module.
Note: As stated in the spec, in addition to an equal number of columns, grid areas must also be rectangular (see this post for more details).
If this:
Is the desired result, then you've only made a minor error.
You've set the grid to be a 2 x 2 square here:
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
But you aren't filling all the space.
grid-template-areas: "logo faq", "about-us";
That line of code is saying "In the top two squares put logo and faq respectively. In the bottom two rows put about-us" and that causes an error. If you want one grid-area to fill the entire space then you need to declare it twice. Thus the above line becomes:
grid-template-areas: "logo faq", "about-us about-us";
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "logo faq", "about-us";
}
.logo {
background-color: blue;
grid-area: logo;
}
.faq {
background-color: red;
grid-area: faq;
}
.aboutUs {
background-color: cyan;
grid-area: about-us;
}
<div class="grid">
<div class="logo">
LOGO
</div>
<div class="faq">
FAq
</div>
<div class="aboutUs">
About-us
</div>
</div>