sticky position on css grid items - html

I've looked at other examples of this on here but can't find one that makes this work. I want the sidebar (section) to be sticky while the page scrolls. the position: sticky works if I put it on the nav, so my browser def supports it.
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
position: sticky;
top: 0;
left: 0;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
<main>
<nav></nav>
<section>
hi
</section>
<article>
<p>hi</p>
</article>
</main>

the problem you are facing here is, that your section block consumes the full height. so it won't stick, since it is too large to do so. you would need to put a child element inside your section and give that your sticky attributes, to make it work. based on your example, i simply wrapped your 'hi' inside a div.
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
}
section div {
position: sticky;
top: 0;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
<main>
<nav></nav>
<section>
<div>
<p>one</p>
</div>
</section>
<article>
<p>two</p>
</article>
</main>

You need to use align-self: start on the thing you want to be sticky.
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
background: grey;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
position: sticky;
top: 0;
left: 0;
align-self: start;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
<main>
<nav></nav>
<section>
hi
</section>
<article>
<p>hi</p>
</article>
</main>

Update with complete code
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
main {
display: grid;
grid-template-columns: 20% 55% 25%;
grid-template-rows: 55px 1fr;
}
nav {
background: blue;
grid-row: 1;
grid-column: 1 / 4;
}
section {
background: grey;
grid-column: 1 / 2;
grid-row: 2;
top: 0;
left: 0;
}
.fixed-section {
position: fixed;
z-index: 1;
overflow-x: hidden;
}
article {
background: yellow;
grid-column: 2 / 4;
}
article p {
padding-bottom: 1500px;
}
</style>
</head>
<body>
<main>
<nav></nav>
<section>
<div class='fixed-section'>
Hi 1
<div>
</section>
<article>
<p>hi</p>
</article>
</main>
</body>
</html>

Related

display: grid aligning divs

I have 3 divs in 3 columns of a grid and I want the middle div to stay static when zoomed in. The one on the right and left growing with the zoom
HTML
<mdiv class="dvCenter">
<div class="dvCenter1"></div>
<div class="dvCenter2"></div>
<div class="dvCenter3"></div>
</div>
CSS
.dvCenter{
background-color: black;
height: 110px;
align-items: center;
display: grid;
grid-template-columns: 40% 20% 40%;
grid-template-rows: 100%;
}
.dvCenter1{
background-color: blue;
height: 80%;
grid-row: 1;
grid-column: 1;
}
.dvCenter2{
background-color: brown;
height: 100%;
grid-row: 1;
grid-column: 2;
}
.dvCenter3{
background-color: blue;
height: 80%;
grid-row: 1;
grid-column: 3;
}
I think what you want is to have the page start by having the .dvCenter2 div to have 20% width and then stays as the current width when the page grows. But % is a relative unit and when the screen grows bigger, the 20% is also bigger than the original 20%.
I can't think of a pure CSS way to do this but you can use javascript to query the current size of the container and modify the grid-template-column. Check the demo below. Hope this helps!
$(".dvCenter").css("grid-template-columns", "1fr " + $(".dvCenter2").width() + "px 1fr");
$("#btn").click(function() {
$(".dvCenter").toggleClass("enlarge");
});
.dvCenter{
background-color: black;
height: 110px;
width: 50%;
align-items: center;
display: grid;
grid-template-columns: 1fr 20% 1fr;
grid-template-rows: 100%;
}
.dvCenter1{
background-color: blue;
height: 80%;
grid-row: 1;
grid-column: 1;
}
.dvCenter2{
background-color: brown;
height: 100%;
grid-row: 1;
grid-column: 2;
}
.dvCenter3{
background-color: blue;
height: 80%;
grid-row: 1;
grid-column: 3;
}
.enlarge {
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<mdiv class="dvCenter">
<div class="dvCenter1"></div>
<div class="dvCenter2"></div>
<div class="dvCenter3"></div>
</div>
<button id="btn">Click to resize container</button>

Blank space at the bottom of my document using CSS grid?

CSS noob here, running into an issue that I can't seem to figure out, my CSS in creating blank space at the bottom of the document, I'd say about 60% of it. Is there something wrong with the parent parameters or the children?
My HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Redacted</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="grid-container">
<ul>
<li>About</li>
<li>Portfolio</li>
<li>Contact</li>
<li><a id="asides" href="asides.asp">Asides</a></li>
</ul>
<p class="intro">
Bacon Ipsum
</p>
<p class="projects">
Lorem Ipsum
</p>
<footer>Footer placeholder</footer>
</div>
<script src="script.js"></script>
</body>
</html>
CSS:
* {
border: 1px solid gold;
}
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
gap: 10px 10px;
grid-auto-flow: row;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
li {
float: left;
}
a {
display: block;
padding: 8px;
background-color: #ffffff;
}
.intro {
grid-column: 1 / span 4;
grid-row: 2;
}
.projects {
grid-column: 1 / span 4;
grid-row: 3;
}
footer {
grid-column: 1 / span 4;
grid-row: 4;
}
body {
background-color: rgb(124, 252, 188);
margin: 0;
padding: 0;
}
Please excuse the terrible formatting, for now, apologies, and thank you in advance!
You forget to add height on body and grid-container
html,
body {
height: 100%;
}
and add height on the grid-container
.grid-container {
height: 100%;
...
}
CODEPEN
* {
border: 1px solid gold;
}
html,
body {
height: 100%;
}
body {
background-color: rgb(124, 252, 188);
margin: 0;
padding: 0;
}
.grid-container {
height: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
gap: 10px 10px;
grid-auto-flow: row;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
li {
float: left;
}
a {
display: block;
padding: 8px;
background-color: #ffffff;
}
.intro {
grid-column: 1 / span 4;
grid-row: 2;
}
.projects {
grid-column: 1 / span 4;
grid-row: 3;
}
footer {
grid-column: 1 / span 4;
grid-row: 4;
}
<div class="grid-container">
<ul>
<li>About</li>
<li>Portfolio</li>
<li>Contact</li>
<li><a id="asides" href="asides.asp">Asides</a></li>
</ul>
<p class="intro">
Bacon Ipsum
</p>
<p class="projects">
Lorem Ipsum
</p>
<footer>Footer placeholder</footer>
</div>

dashboard layout with multiple column on header and footer

I am using grids for admin dashboard. The design I am trying is there will be two column on header where on the left there will be a logo and the right one will be responsible for something like menu bar. The second row will be of sidebar and main body. The last row will be the footer but on the left it should have setting or logout button which should be fixed. I tried but i could not divide the header and footer into two column.
here is what I am trying to do. I hope it will be clear what i am trying to say
.dashboard {
display: grid;
grid-template-rows: auto 1fr;
grid-template-columns: auto 1fr;
height: 100vh;
}
header {
background: blue;
grid-column: 1/-1;
grid-row: 1;
}
aside {
background-color: #00152b;
grid-row:2/3;
grid-column:1;
width: 200px;
}
main {
background: #acacd71c;
grid-row: 2;
grid-column: 2;
}
footer {
grid-row: 4;
grid-column:2;
}
.fixed-logout-btn {
position: absolute;
bottom: 0;
background: blue;
display: flex;
width: 180px;
}
<div class="dashboard">
<header>
<div class="left">
logo
</div>
<div class="right">
menu bar
</div>
</header>
<aside>
<p>aside</p>
<div class="fixed-logout-btn">
<p>logout</p>
</div>
</aside>
<main>
<p>main</p>
</main>
<footer>
<p>copyright</p>
</footer>
</div>
This is the expected one
Maybe this works for you. I don't think you were containing your menu bar correctly the .right class.
.dashboard {
display: grid;
grid-template-rows: auto 1fr;
grid-template-columns: auto 1fr;
height: 100vh;
}
header {
background: blue;
grid-column: 1/-1;
grid-row: 1;
}
aside {
background-color: #00152b;
color: grey;
grid-row:2/3;
grid-column:1;
width: 200px;
}
main {
background: #acacd71c;
grid-row: 2;
grid-column: 2;
}
footer {
grid-row: 4;
grid-column:2;
}
.fixed-logout-btn {
position: absolute;
bottom: 0;
background: yellow;
display: flex;
width: 200px;
}
.right {
grid-row: 1;
grid-column: 2;
background-color: red;
}
<div class="dashboard">
<header>
<div class="left">
logo
</div>
</header>
<div class="right">
menu bar
</div>
<aside>
<p>aside</p>
<div class="fixed-logout-btn">
<p>logout</p>
</div>
</aside>
<main>
<p>main</p>
</main>
<footer>
<p>copyright</p>
</footer>
</div>

Grid item won't take full height of parent container

I am trying to create three items inside of a nested grid item. As you can see from the code, I've put the 'panels' div in-between the 'jumbo' and 'content' divs. I also nested three divs inside. In the CSS, I added a nested grid inside of .panels.
I want the 'panels' div to be split in three equally size parts on the vertical axis. Imagine three square blocks stack one after another. But the nested items don't fill the entire 'panels' div. If you run the code snippet, you can see that the panels are nested but don't take up the entire space. They take up a small percentage of their parent. I added background-color: white !important to one of the nested panels to show how small it is.
Another example can be seen here: https://codepen.io/rachelandrew/pen/NqQPBR/
But again, the nested E, F and G items don't expand to fill up the entire D section.
Is there a way to make the three panels fill in their parent?
.container {
display: grid;
width: 100%;
height: 100%;
grid-gap: 3px;
grid-template-columns: repeat(10, 1fr);
grid-template-rows: 40px 130px 130px 130px 60px 330px 40px;
}
.header {
grid-column: 1 / -1;
}
.jumbo {
grid-column: 1 / -1;
grid-row: 2 / 5;
}
.panels {
grid-column: 3 / 9;
grid-row: 4 / 6;
z-index: 1;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.panel1 {
grid-row: 1 / 2;
grid-row: 1;
background-color: white !important;
z-index: 2;
}
.content {
grid-column: 1 / -1;
grid-row: 5 / 7;
}
.footer {
grid-column: 1 / -1;
}
/* Styling */
.container > div {
display: grid;
justify-content: center;
align-items: center;
font-size: 2em;
color: #ffeead;
}
html, body {
background-color: #ffeead;
box-sizing: border-box;
height: 100%;
margin: 0px;
font-family: "Work Sans"
}
.container > div:nth-child(1n) {
background-color: #96ceb4;
}
.container > div:nth-child(3n) {
background-color: #88d8b0;
}
.container > div:nth-child(2n) {
background-color: #ff6f69;
}
.container > div:nth-child(4n) {
background-color: #ffcc5c;
}
.panels > div:nth-child(1n) {
background-color: #96ceb4;
}
<div class="container">
<div class="header">
HEADER
</div>
<div class="jumbo">
JUMBO
</div>
<div class="panels">
<div class="panel1">PANEL1</div>
<div class="panel2">PANEL2</div>
<div class="panel3">PANEL3</div>
</div>
<div class="content">
CONTENT
</div>
<div class="footer">
FOOTER
</div>
</div>
You have align-items: center applied to the nested grid container (.panels).
With that rule, you override the default align-items: stretch, which would set your grid items to the full height of the parent. Instead, you have the items vertically centered.
So they can be full height, remove align-items: center from the .panels element:
.container > div:not(.panels) {
align-items: center;
}
.container {
display: grid;
width: 100%;
height: 100%;
grid-gap: 3px;
grid-template-columns: repeat(10, 1fr);
grid-template-rows: 40px 130px 130px 130px 60px 330px 40px;
}
.header {
grid-column: 1 / -1;
}
.jumbo {
grid-column: 1 / -1;
grid-row: 2 / 5;
}
.panels {
grid-column: 3 / 9;
grid-row: 4 / 6;
z-index: 1;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.panel1 {
grid-row: 1 / 2;
grid-row: 1;
background-color: white !important;
z-index: 2;
}
.content {
grid-column: 1 / -1;
grid-row: 5 / 7;
}
.footer {
grid-column: 1 / -1;
}
/* Styling */
.container > div {
display: grid;
justify-content: center;
/* align-items: center; */
font-size: 2em;
color: #ffeead;
}
/* new */
.container > div:not(.panels) {
align-items: center;
}
html, body {
background-color: #ffeead;
box-sizing: border-box;
height: 100%;
margin: 0px;
font-family: "Work Sans"
}
.container > div:nth-child(1n) { background-color: #96ceb4; }
.container > div:nth-child(3n) { background-color: #88d8b0; }
.container > div:nth-child(2n) { background-color: #ff6f69; }
.container > div:nth-child(4n) { background-color: #ffcc5c; }
.panels > div:nth-child(1n) { background-color: #96ceb4; }
<div class="container">
<div class="header">HEADER</div>
<div class="jumbo">JUMBO</div>
<div class="panels">
<div class="panel1">PANEL1</div>
<div class="panel2">PANEL2</div>
<div class="panel3">PANEL3</div>
</div>
<div class="content">CONTENT</div>
<div class="footer">FOOTER</div>
</div>
Then, to vertically center the content of .panels, I would target the content directly:
.panels > div {
display: flex;
align-items: center;
}
.container {
display: grid;
width: 100%;
height: 100%;
grid-gap: 3px;
grid-template-columns: repeat(10, 1fr);
grid-template-rows: 40px 130px 130px 130px 60px 330px 40px;
}
.header {
grid-column: 1 / -1;
}
.jumbo {
grid-column: 1 / -1;
grid-row: 2 / 5;
}
.panels {
grid-column: 3 / 9;
grid-row: 4 / 6;
z-index: 1;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.panel1 {
grid-row: 1 / 2;
grid-row: 1;
background-color: white !important;
z-index: 2;
}
.content {
grid-column: 1 / -1;
grid-row: 5 / 7;
}
.footer {
grid-column: 1 / -1;
}
/* Styling */
.container > div {
display: grid;
justify-content: center;
/* align-items: center; */
font-size: 2em;
color: #ffeead;
}
/* new */
.container > div:not(.panels) {
align-items: center;
}
/* new */
.panels > div {
display: flex;
align-items: center;
}
html, body {
background-color: #ffeead;
box-sizing: border-box;
height: 100%;
margin: 0px;
font-family: "Work Sans"
}
.container > div:nth-child(1n) { background-color: #96ceb4; }
.container > div:nth-child(3n) { background-color: #88d8b0; }
.container > div:nth-child(2n) { background-color: #ff6f69; }
.container > div:nth-child(4n) { background-color: #ffcc5c; }
.panels > div:nth-child(1n) { background-color: #96ceb4; }
<div class="container">
<div class="header">HEADER</div>
<div class="jumbo">JUMBO</div>
<div class="panels">
<div class="panel1">PANEL1</div>
<div class="panel2">PANEL2</div>
<div class="panel3">PANEL3</div>
</div>
<div class="content">CONTENT</div>
<div class="footer">FOOTER</div>
</div>
Keep in mind that there are three structural levels in a grid container:
the container
the item (child of the container)
the content (child of the item)
Grid properties only work between parent and child.
So when you apply grid centering properties on the container, they apply to the item, not the content. To center the content, you need to treat the item as parent and content as child.
There's a more in-depth explanation of these concepts and methods here: Centering in CSS Grid
Well, what you have done is, you created three columns inside the 'panels' div:
grid-template-columns: repeat(3, 1fr);
But you gave the children only a position for the row (twice):
grid-row: 1 / 2;
grid-row: 1;
So if you change 'columns' to 'rows' in '.panels' and clean up the code for '.panel1' it should work like a cham!
Thank you all for your suggestions. I solved the issue by removing the nested 'panel' and simply creating three different panels to fill the same space.
.container {
display: grid;
width: 100%;
height: 100%;
grid-gap: 3px;
grid-template-columns: repeat(13, 1fr);
grid-template-rows: 50px 218px 218px 200px 80px 530px 40px;
}
.header {
grid-column: 1 / -1;
position: sticky;
top: 0;
z-index: 3;
}
.jumbo {
grid-column: 1 / -1;
grid-row: 2 / 5;
}
.panel1 {
background-color: white !important;
z-index: 1;
grid-column: 3 / 6;
grid-row: 4 / 6;
}
.panel2 {
background-color: black !important;
z-index: 1;
grid-column: 6 / 9;
grid-row: 4 / 6;
}
.panel3 {
background-color: purple !important;
z-index: 2;
grid-column: 9 / 12;
grid-row: 4 / 6;
}
.content-left {
grid-column: 1 / 5;
grid-row: 5 / 7;
}
.content-right {
grid-column: 5 / -1;
grid-row: 5 / 7;
display: grid;
grid-gap: 5px;
align-items: start;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr)
}
.content-right > div {
background-color: white;
z-index: 2;
}
.footer {
grid-column: 1 / -1;
}
.container > div {
justify-content: center;
align-items: center;
font-size: 2em;
color: #ffeead;
}
html, body {
background-color: #ffeead;
box-sizing: border-box;
height: 100%;
margin: 0px;
font-family: "Work Sans"
}
.container > div:nth-child(1n) {
background-color: #96ceb4;
}
.container > div:nth-child(3n) {
background-color: #88d8b0;
}
.container > div:nth-child(2n) {
background-color: #ff6f69;
}
.container > div:nth-child(4n) {
background-color: #ffcc5c;
}
.panels > div:nth-child(1n) {
background-color: #96ceb4;
}
<div class="container">
<div class="header">
HEADER
</div>
<div class="jumbo">
JUMBO
</div>
<div class="panel1">PANEL1</div>
<div class="panel2">PANEL2</div>
<div class="panel3">PANEL3</div>
<div class="content-left">
CONTENT-LEFT
</div>
<div class="content-right">
<div class="content-right1">1</div>
<div class="content-right2">2</div>
<div class="content-right3">3</div>
<div class="content-right4">4</div>
<div class="content-right5">5</div>
<div class="content-right6">6</div>
</div>
<div class="footer">
FOOTER
</div>
</div>

rows overlapping in CSS Grid Layout

How can I prevent the footer row from overlapping the content row?
This is what I'm getting:
body {
display: grid;
grid-template-rows: 3.7rem auto auto;
grid-template-columns: 3rem 3fr 2fr;
}
*[role="banner"] {
grid-row: 1;
grid-column: 2/4;
background-color: green;
height: 3rem;
}
*[role="main"] {
grid-row: 2;
grid-column: 2;
background-color: yellow;
height: 100px;
}
*[role="contentinfo"] {
grid-row: 3;
grid-column: 2/3;
border-top: 1px solid black;
}
*[role="contentinfo"] img {
height: 100px;
}
<div role="banner"></div>
<article role="main"><p>Some Text.</p><p>Some more text</p><p>the last text</p></article>
<footer role="contentinfo"><img src="https://s14-eu5.ixquick.com/cgi-bin/serveimage?url=https%3A%2F%2Fdata.motor-talk.de%2Fdata%2Fgalleries%2F0%2F147%2F9424%2F43109894%2Fbild--7008737403287221413.jpg&sp=6a4eaf3bd8ff58ca9d9bba2e3519888e"></footer>
The footer (row 3) is overlapping the article (row 2) because you have a fixed height on the article:
[role="main"] { height: 100px; }
The overrides the auto height you have specified on the grid container with:
grid-template-rows: 3.7rem auto auto
Once you remove the height rule, the overlap is gone.
body {
display: grid;
grid-template-rows: 3.7rem auto auto;
grid-template-columns: 3rem 3fr 2fr;
}
*[role="banner"] {
grid-row: 1;
grid-column: 2/4;
background-color: green;
height: 3rem;
}
*[role="main"] {
grid-row: 2;
grid-column: 2;
background-color: yellow;
/* height: 100px; <-------- REMOVE */
}
*[role="contentinfo"] {
grid-row: 3;
grid-column: 2/3;
border-top: 1px solid black;
}
*[role="contentinfo"] img {
height: 100px;
}
<div role="banner"></div>
<article role="main"><p>Some Text.</p><p>Some more text</p><p>the last text</p></article>
<footer role="contentinfo"><img src="https://s14-eu5.ixquick.com/cgi-bin/serveimage?url=https%3A%2F%2Fdata.motor-talk.de%2Fdata%2Fgalleries%2F0%2F147%2F9424%2F43109894%2Fbild--7008737403287221413.jpg&sp=6a4eaf3bd8ff58ca9d9bba2e3519888e"></footer>