How to structure a grid layout - css

So I'm having trouble with the following CSS:
const Content = styled("div")`
grid-area: main;
background-color: white;
margin-top: 5px;
margin-left: 20px;
margin-right: 20px;
display: grid;
grid-template-areas:
"contentHeader contentHeader contentHeader"
"contentItem contentItem contentItem"
"contentItem contentItem contentItem";
/* grid-template-columns: 1fr; */
/* grid-auto-columns: 33px;
grid-auto-rows: 150px; */
grid-gap: 10px;
`;
const ContentHeader = styled("h1")`
grid-area: contentHeader;
font-family: Roboto;
font-style: normal;
font-weight: bold;
font-size: 32px;
line-height: 40px;
color: black;
`;
const ContentMain = styled("div")`
grid-column: 1fr;
grid-row: 1fr;
background-color: red;
`;
I'm aiming for a layout which has the header on the top left, and then two rows.
The first row would have two columns, and the first item would be larger than the second. The second row would have one item which filled both columns.
Instead I get this:
I know the issue is likely in my grid-column line, but it'd be great if someone could point me in the right direction. Also, I don't understand why I have huge gaps between my header and the coloured grid items?
Thanks!

you need to name each one of your content items in template area:
ex:
grid-template-areas:
"contentHeader contentHeader contentHeader"
"contentItem1 contentItem1 contentItem2"
"contentItem3 contentItem3 contentItem3";
then in your contentItem1 add this to css:
grid-area: contentItem1
in contentItem2 div add this to css:
grid-area: contentItem2
finally in contentItem3 add this to css:
grid-area: contentItem3
this is css only demo:
.grid {
display: grid;
grid-template-areas: "contentHeader contentHeader contentHeader" "contentItem1 contentItem1 contentItem2" "contentItem3 contentItem3 contentItem3";
grid-gap: 10px
}
.header {
grid-area: contentHeader;
background-color: red;
height: 50px
}
.item1 {
grid-area: contentItem1;
background-color: blue;
height: 150px;
}
.item2 {
grid-area: contentItem2;
background-color: green;
height: 150px;
}
.item3 {
grid-area: contentItem3;
background-color: yellowgreen;
height: 150px;
}
<div class="grid">
<div class="header"></div>
<div class="item1"></div>
<div class="item2"></div>
<div class="item3"></div>
</div>

Related

CSS Grid 2 columns and 1 row, H1 creates new row

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;
}

CSS Grid - Centering header section (Logo + Menu)

I am investigating into CSS and Grid right now, as I want to learn new things. Actually, I do have a very simple question (I guess) but I am unable to resolve this. I am trying to use CSS grid for making a simple responsive design. For that purpose, I want to have a header section in which I do have a logo and a menu centered with a maximum width of 1170 px. However, I am unable to center the header-wrapper. Maybe I am doing things wrong here. For a better understanding, I just put a jsiddler here.
https://jsfiddle.net/f7ywrg93/
.wrapper {
display: grid;
grid-template-columns: auto;
grid-template-rows: 100px auto;
grid-template-areas:
"header"
"promo";
grid-gap: 10px;
}
.header {
grid-area: header;
background-color: #20262e;
color: #fff;
font-size: 14px;
}
.promo {
grid-area: promo;
background-color: #c0ff3e;
}
.wrapper-header {
display: grid;
grid-template-columns: auto auto;
grid-template-rows: auto;
grid-template-areas: "logo menu";
max-width:1170px;
grid-gap: 20px;
background-color: #447666;
}
.logo {
grid-area: logo;
place-self: start;
max-width: 300px;
background-color: #545454;
}
.menu {
grid-area: menu;
place-self: end;
background-color: #eadead;
}
<div class="wrapper">
<div class="header">
<div class="wrapper-header">
<div class="logo">Logo</div>
<div class="menu">Menu</div>
</div>
</div>
<div class="promo">Promo</div>
</div>
Hope that one can give me some give me some idea what I am doing wrong.
If you swap place-self: start and place-self: end for the logo and menu it will center them:
.wrapper {
display: grid;
grid-template-columns: auto;
grid-template-rows: 100px auto;
grid-template-areas:
"header"
"promo";
grid-gap: 10px;
}
.header {
grid-area: header;
background-color: #20262e;
position: relative;
color: #fff;
font-size: 14px;
}
.promo {
grid-area: promo;
background-color: #c0ff3e;
}
.wrapper-header {
display: grid;
grid-template-columns: auto auto;
grid-template-rows: auto;
grid-template-areas: "logo menu";
max-width:1170px;
width: 100%;
grid-gap: 20px;
margin: 0 auto;
background-color: #447666;
}
.logo {
grid-area: logo;
place-self: end;
max-width: 300px;
background-color: #545454;
}
.menu {
grid-area: menu;
place-self: start;
background-color: #eadead;
}
<div class="wrapper">
<div class="header">
<div class="wrapper-header">
<div class="logo">Logo</div>
<div class="menu">Menu</div>
</div>
</div>
<div class="promo">Promo</div>
</div>
place-self positions the elements within their respective grid blocks and not within the container element itself.

How to overlap image tag as a background over two CSS Grid areas

The image is an img tag and needs to be stretched as a background image over two areas 'img' and 'content'. The text has to go above the stretched image in the 'content' area. Simple but how? I can't find any obvious answers online.
.media {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
width: 100%
}
.media {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-areas: "img content";
margin-bottom: 1em;
}
.image {
grid-area: img;
background-color: #ffd8a8;
}
.text {
grid-area: content;
padding: 10px;
}
<div class="media">
<img class="image" src="https://loremflickr.com/500/200" />
<div class="text">This is a media object example.
  We can use grid-template-areas to switch around the image and text part of the media object.
  </div>
</div>
Modify your code as follows:
.media {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
width: 100%
}
.media {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-areas: "img content";
margin-bottom: 1em;
}
.image {
grid-area: img;
background-color: #ffd8a8;
}
.text {
grid-area: content;
padding: 10px;
}
.media {
background-image: url("https://loremflickr.com/700/200");
background-repeat: no-repeat;
height: 150px;
}
<div class="media">
<div class="text">This is a media object example. We can use grid-template-areas to switch around the image and text part of the media object.
</div>
</div>
Here is a screenshot of the output:
There are many ways to get the desired result.
You could also make the image a background of the DIV rather than having an IMG tag inside the DIV.
But I sticked to your code below and just added CSS to place the text DIV on top of the image and stretch the image to 100% with hidden overflow.
.media {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
width: 100% display: grid;
grid-template-columns: 1fr 1fr;
grid-template-areas: "img content";
margin-bottom: 1em;
overflow: hidden;
}
.image {
grid-area: img;
background-color: #ffd8a8;
width: 100%;
float: left;
}
.text {
grid-area: content;
padding: 10px;
position: absolute;
top: 10px;
left: 10px;
color: white;
text-shadow: 1px 1px 2px black;
box-sizing: border-box;
}
<div class="media">
<img class="image" src="https://loremflickr.com/500/200" />
<div class="text"><b>This is a media object example.
  We can use grid-template-areas to switch around the image and text part of the media object.</b>   </div>
</div>
I think, if there is just one part of the page at the background of the page, you should create a style. Then look at the backgammon tag select whatever you want,Later, the ID will have it in created anything on the page, for example
Panel, td, div,.... get it there.
You do not need to add any image.
Have you tried position: absolute on the text div?
I figured it out if anyone stumbles across it: (make sure you preview with full page)
#container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 100px;
grid-template-areas: "empty text" "mobile mobile";
}
#container img {
grid-column: 1 / span 2;
grid-row: 1 / span 1;
width: 100%;
overflow: hidden;
}
#container p {
grid-area: text;
color: red;
align-self: center;
justify-self: center;
z-index: 1;
}
#media (max-width: 768px) {
#container p {
grid-area: mobile;
color: red;
align-self: center;
justify-self: center;
z-index: 1;
}
}
<div id="container">
<img src="https://loremflickr.com/500/200">
<p>SOME TEXT OVER IMAGE</p>
</div>

CSS grid creating disproportionate layouts when using fractions and screen size percentage

I have been having some trouble getting CSS Grid to work properly with my React App. When I use grid-template-columns: 1fr 3fr 1fr;, one of the 1fr columns is much smaller than the other (so the space on the right is much smaller than the space created on the left in comparison to the middle column). Is there any particular reason why this would be? Here is the rest of my CSS:
#main-body {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
grid-auto-rows: 100px;
background-color: white;
}
#main-header {
color: white;
background-color: darkcyan;
grid-column-start: 2;
grid-row-start: 1;
text-align: center;
display: inline;
}
#quote-render-block {
text-align: center;
background-color: orange;
grid-column: 2;
grid-row-start: 2;
}
There may be another child react component apart from the main-body or some styling for the parent component that is creating the issue. You can view a codepen of your code here: https://codepen.io/sakettawde/pen/yxvoxM
HTML:
<div class="main-body">
<div class="main-header">
</div>
<div class="quote-render-block">
</div>
</div>
CSS:
.main-body {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
grid-auto-rows: 100px;
background-color: white;
}
.main-header {
color: white;
background-color: darkcyan;
grid-column-start: 2;
grid-row-start: 1;
text-align: center;
display: inline;
}
.quote-render-block {
text-align: center;
background-color: orange;
grid-column: 2;
grid-row-start: 2;
}
It is possible that a parent element has a "padding-right" CSS attribute that is shifting the contents of the screen.

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>

Resources