CSS Grid - Centering header section (Logo + Menu) - css

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.

Related

center all grid items in the middle with even spaces

Trying to evenly space out all grid items in the middle of the page:
App Component:
return (
<div className="App">
<div className="App__box">
<Box />
</div>
</div>
);
}```
App Css:
.App {
$large-screen: 1024px;
$xlarge-screen: 1280px;
text-align: center;
&__box {
display: grid;
grid-template-columns: auto auto auto;
grid-gap: 16px 16px;
}
#media (min-width: $large-screen) {
&__box {
grid-template-columns: repeat(2, 2fr);
justify-items: center;
}
}
}
Ps the desired outcome i am trying to achive for the `$large-screen` breakpoint
fix the with with max-width property
then give it
margin: 0 auto;
width: 100%;
If I have understood the question, it's possible by using justify-self and nth-child. see code:
.boxes {
display: grid;
grid-template-columns: repeat(2, 2fr);
grid-gap: 16px 16px;
}
.box {
width: 10rem;
padding: 1rem;
text-align: center;
background-color: red;
justify-self: end;
}
.box:nth-child(2) {
background-color: blue;
justify-self: start;
}
<div class="App">
<div class="boxes">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
</div>
You could try using a
{
display: flex;
flex-wrap: wrap;
}
and try out justify-content prop for parent component, and for child components could use flex-grow prop.
Check out:
https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox

How to structure a grid layout

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>

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>

Puzzled by column span in CSS grid not working as expected

I am trying to build a layout with a full-width header, then two 150px wide ad blocks stacked vertically on the left, the main part in the center, then two more ad blocks stacked vertically on the right, with a full-width footer at the bottom.
The code I expected to work is
.container {
display: grid;
grid-gap: 2px;
background-color: black;
padding: 2px;
min-height: 300px;
width: 100%;
margin: 0 auto;
--nav-width: 250px;
}
.container {
grid-template-columns: 150px 1fr 150px; /*Three columns - 150px for the ads; rest of screen for main */
grid-template-rows: 200px 1fr 1fr 40px;
grid-template-areas:
"header header header"
"left_ad1 main right_ad1"
"left_ad2 main right_ad2"
"footer footer footer";
}
.header {
background:PaleTurquoise;
}
.nav {
background:LightPink;
}
.content {
background:red;
}
.footer {
background:blue;
}
div {
font-size: 28px;
}
body {
text-align: center;
}
.ad {
height: 250px;
}
header {
background: LightSalmon;
}
#left_ad1 {
background:PaleTurquoise;
grid-area: left_ad1;
}
#left_ad2 {
background:PaleTurquoise;
grid-area: left_ad2;
}
#right_ad1 {
background:LightPink;
grid-area: right_ad1;
}
#right_ad2 {
background:LightPink;
grid-area: right_ad2;
}
main {
background-color: red;
grid-area: main;
}
footer {
background: LightSkyBlue;
grid-area: footer;
}
<div class="container">
<header>Header</header>
<div id="left_ad1">Left ad 1</div>
<main>Main</main>
<div id="right_ad1" class="ad">Right ad 1</div>
<div id="left_ad2" class="ad">Left ad 2</div>
<div id="right_ad2" class="ad">Right ad 2</div>
<footer>Footer</footer>
</div>
but this makes the header fill just the left-most cell of the top row.
I can get it to work by adding
header {
grid-column: 1 / 4;
}
to force the header to span the whole width of the grid, but surely that shouldn't be needed? The use of grid-template-areas: "header header header" should achieve that without the use of grid-column shouldn't it?
Confused! Any help appreciated!
You need to specify grid-area: header; on your header element.
.container {
display: grid;
grid-gap: 2px;
background-color: black;
padding: 2px;
min-height: 300px;
width: 100%;
margin: 0 auto;
--nav-width: 250px;
}
.container {
grid-template-columns: 150px 1fr 150px; /*Three columns - 150px for the ads; rest of screen for main */
grid-template-rows: 200px 1fr 1fr 40px;
grid-template-areas:
"header header header"
"left_ad1 main right_ad1"
"left_ad2 main right_ad2"
"footer footer footer";
}
div {
font-size: 28px;
}
body {
text-align: center;
}
.ad {
height: 250px;
}
header {
background: LightSalmon;
grid-area: header;
}
#left_ad1 {
background:PaleTurquoise;
grid-area: left_ad1;
}
#left_ad2 {
background:PaleTurquoise;
grid-area: left_ad2;
}
#right_ad1 {
background:LightPink;
grid-area: right_ad1;
}
#right_ad2 {
background:LightPink;
grid-area: right_ad2;
}
main {
background-color: red;
grid-area: main;
}
footer {
background: LightSkyBlue;
grid-area: footer;
}
<div class="container">
<header>Header</header>
<main>Main</main>
<footer>Footer</footer>
<div id="left_ad1">Left ad 1</div>
<div id="left_ad2" class="ad">Left ad 2</div>
<div id="right_ad1" class="ad">Right ad 1</div>
<div id="right_ad2" class="ad">Right ad 2</div>
</div>

Is it possible to split a grid item to allow different spans?

I have an article and an aside (sidebar) element - easy, except the title and sub-heading of the article need to span the entire row. If I take the title/sub-heading out of the article, the article element is no longer semantically complete.
Is there a way, using CSS Grid, to have the format below, where Title, Sub and Content are all a part of an "Article" element, and "Aside" is the second in a 2 column grid?
From my research so far, it seems this is not possible.
You can hack your way through using nested CSS grid if you know:
The width of the aside section
The height of the title and sub heading sections
(in many layouts, these dimensions are fixed)
You can use a pseudo element that create a space for the aside element and then sneak it inside the outer grid container - check out the demo below:
body {
margin: 0;
}
* {
box-sizing: border-box;
}
article,
aside {
border: 1px solid;
display: flex;
align-items: center;
justify-content: center;
}
div {
display: grid;
grid-template-areas: "section aside";
}
section {
grid-area: section;
display: grid;
grid-template-areas: "header header" "subhead subhead" "content empty";
grid-template-rows: 50px 50px auto;
grid-template-columns: 80vw auto;
height: 100vh;
width: 100vw;
}
section article:first-child {
grid-area: header;
}
section article:nth-child(2) {
grid-area: subhead;
}
section article:last-child {
grid-area: content;
}
section:after {
content: '';
display: block;
grid-area: empty;
}
aside {
grid-area: aside;
height: calc(100vh - 100px);
width: 20vw;
align-self: flex-end;
position:relative;
transform: translateX(-100%);
}
<div>
<section>
<article>Article title</article>
<article>Article sub-heading</article>
<article>Article content</article>
</section>
<aside>Aside</aside>
</div>
You can use something like this.
* {box-sizing: border-box;}
.wrapper {
max-width: 940px;
margin: 0 auto;
}
.wrapper > div {
border: 2px solid rgb(233,171,88);
border-radius: 5px;
background-color: rgba(233,171,88,.5);
padding: 10px;
color: #d9480f;
}.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
grid-auto-rows: minmax(100px, auto);
}
.one {
grid-column: 1 / 4;
grid-row: 1;
}
.two {
grid-column: 1 / 4;
grid-row: 2;
}
.three {
grid-column: 1 / 3;
grid-row: 3;
min-height:200px;
}
.four {
grid-column: 3;
grid-row: 3;
min-height:200px;
}
<div class="wrapper">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
<div class="four">Four</div>
</div>
Also check Fiddle.
And for more details please visit https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout
You can achieve that by simply floating all the cells, as long as the article doesn't float - https://jsfiddle.net/yxbckzcq/1/
<div class="wrapper">
<article>
<div style="float:left;width:100%" class="one">One</div>
<div style="float:left;width:100%" class="two">Two</div>
<div style="float:left;width:70%" class="three">Three</div>
</article>
<div style="float:left;width:30%" class="four">Four</div>
</div>

Resources