I'm currently making a NextJS app which should have a fullscreen layout that does not change regardless of zoom level. At default zoom level, you see the header, footer, toolbar, and vertically-scrollable content window
When you zoom out, the size of the header, footer, toolbar, and content window remain fixed even if the content inside them changes size
Note that there are multiple types of toolbars and content windows that may be shown depending on what the user selects. I've been able to get a header and footer working by editing _app.js, but the toolbar and content window are not taking up the full remaining space if I zoom out because there is some extra div that is injected by NextJS at some point. I'm using inline styling with material UI.
Has anyone run into this issue before?
This is one approach you could use for your layout, using CSS Grid. I'm defining the grid to have 12 columns, but you could set it up in any way you'd like.
Note, the following block means, start from the 3rd grid line and span to the end of the grid. This will satisfy your horizontal space requirements.
main .main-content {
grid-column: 3 / -1;
}
For the center column taking up the maximum space of the viewport, I'm using the following:
grid-template-rows: auto 1fr auto;
The first auto is the header, the 1fr is the middle section (most room), and the last auto is the footer.
Here's a demo.
.grid {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
min-height: 100dvh;
gap: 0.5rem;
padding: 0.5rem;
}
main {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 0.5rem;
}
main aside {
grid-column: 1 / 3;
}
main .main-content {
grid-column: 3 / -1;
}
header, main aside, .main-content, footer {
background-color: #eee;
}
header,
footer,
main :where(aside, .main-content) { padding: 0.5rem;}
html, body { padding: 0; margin: 0; }
*, *::before, *::after {
box-sizing: border-box;
}
<div class="grid">
<header>header</header>
<main>
<aside>aside</aside>
<div class="main-content">main content</div>
</main>
<footer>footer</footer>
</div>
Related
I am trying to come up with a solution for advanced layout. I decided to use a css grid as it seemed to be the best match for my needs.
The requirements:
Header - consists of three elements - logo, search bar and menu
search bar should be aligned with the main content if space allows, i.e. on small screen search bar doesn't need to start where the main content starts but it should end where main content ends or take all available space
Main - consists of content and sidebar- should be centred and take max 100rem width space
content should be 2 times bigger than the sidebar
main content should have at least 1rem space from left and right
This is how it looks now. It matches my requirements on big screens (4k) but when the screen gets smaller it gets messy. I would really like to avoid any javascript and solve this with pure CSS if possible.
How would you approach this problem? I am now more inclining that this is not solvable with pure CSS and JS is needed. (Probably some resize observer on main-content element)
Examples:
Big screen -> alignment is correct ✔️
Small screen -> alignment is not correct. ❌ The search box should be within the black "brackets"
Even smaller screen -> alignment is not correct too. ❌ The search box should expand up to the black line
html,
body {
padding: 0;
margin: 0;
}
body {
font-family: sans-serif;
display: grid;
grid-template-columns: minmax(1rem, 1fr) minmax(min-content, 100rem) minmax(
1rem,
1fr
);
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
". main .";
min-height: 100vh;
}
.header {
padding: 1rem 1rem;
background: green;
grid-area: header;
display: grid;
grid-template-columns: minmax(max-content, 1fr) minmax(min-content, 100rem) minmax(
max-content,
1fr
);
}
.search-box {
background: yellow;
max-width: calc(2/3 * 100%);
}
.logo {
background: yellowgreen;
min-width: 5rem;
}
.menu {
background: brown;
}
.main {
grid-area: main;
display: flex;
}
.main-content {
background: red;
flex: 2;
}
.sidebar {
background: blue;
flex: 1;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="header">
<div class="logo">Logo</div>
<div class="search-box">
Search box should should match main content position
</div>
<div class="menu">Menu with two submenus at least</div>
</header>
<main class="main">
<section class="main-content">Main content</section>
<aside class="sidebar">Sidebar</aside>
</main>
</body>
</html>
Sandbox available here
I'm trying to position images the way shown in the picture using CSS Grid and I can't find a right solution.
Right now I'm simply changing the grid flow to column, but the grid elements don't jump to another row when they meet the end of the container - they resize it and stay in the same, first row.
I tried to use grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)) - it solves this jump to another line issue, but it gives all the elements a fixed width whereas some images are not that wide. It creates empty holes between images which I'd like to avoid.
Any ideas on how to accomplish it?
wrong solution 1
Code from the image above:
container {
display: grid;
grid-gap: 1rem;
grid-auto-flow: column;
}
photo { // all container's elements have this class
height: 10rem;
width: auto;
}
wrong solution 2
Code from the image above:
container {
display: grid;
grid-gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}
photo {
height: 10rem;
max-width: 100%;
}
You see, this is tusk for flex, not for grid. Using grid means columns with same width on each row. No need here at all.
html {
font-size: 10px;
}
.conteiner {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.photo {
height: 10rem;
margin: 0 1rem 1rem 0;
}
.photo img {
width: auto;
height: 100%;
}
<div class="conteiner">
<div class="photo"><img src="https://via.placeholder.com/500x200"></div>
<div class="photo"><img src="https://via.placeholder.com/300x200"></div>
<div class="photo"><img src="https://via.placeholder.com/200x200"></div>
<div class="photo"><img src="https://via.placeholder.com/400x200"></div>
<div class="photo"><img src="https://via.placeholder.com/500x200"></div>
<div class="photo"><img src="https://via.placeholder.com/300x200"></div>
<div class="photo"><img src="https://via.placeholder.com/200x200"></div>
</div>
Although I'm using Justified gallery jQuery plugin, if I wand all images in each row to fill all the width.
Is there a way to stick the footer on a page to the bottom of the body content is shorter? I mean if the body content will be longer the footer should be displayed at the end of the whole content. The usage of the layout is not acceptable.
I tried:
.my-footer {
min-height: 1vp -heightOfHeader - heightOfFooter;
}
But I wish to get the values dynamically without JS. Only using CSS. Is it possible?
I don't know what you mean by "The usage of the layout is not acceptable", but one way to achieve this is to use grid display.
body, html {
margin: 0;
}
body {
min-height: 100vh;
display: grid;
grid-template-rows: 1fr auto;
}
.main-content {
grid-row: 1 / 2;
}
footer {
grid-row: 2 / 3;
}
<div class="main-content">Main content</div>
<footer>footer</footer>
I am setting up a template for for demos on how to use a certain portion of a program. I have set up the pages in an 8-column grid layout with an empty 1fr column on either side for padding. The problem I am running into is putting a background color behind the content to offset the content as the user scrolls down the page. I'm having trouble coming up with a solution that spans the background color across the entire viewport width, while keeping the content within the 8 grids.
I have tried adding another class to the tag named "bg". I did this to span the bg color across the entire viewport, but then it forces the content outside of the center 8 grids which I don't want the content to escape from. I've also tried giving .bg a width of 100vw, but it then overrides the content grid again.
Html
<div class="container">
<section class="cont2 bg">
<img src="img/perf-2.png" alt="" class="cont2__img">
<div class="cont2__content">
<p class="cont2__content--p-1">
For this example, we are looking at the effects of investing $10,000 in JNJ with a start date of December 1998, and how today that money would be worth about $40,566.
</p>
<p class="cont2__content--p-2">
These performance results located at the bottom you can find the average dividend growth rate for the timeframe selected with the compounded annual growth rate, the total amount of dividends paid, and the growth breakdown of the stock you are looking at.
</p>
<p class="cont2__content--p-3">
This is then in comparison to investing in the S&P 500 over the same timeframe.
</p>
</div>
</section>
</div>
CSS (sass)
// Container Grid layout
.container {
display: grid;
grid-template-rows: 20vh repeat(4, min-content); // I have 4 content sections for the entire project, so that's why there is repeat 4
grid-template-columns: [full-start] minmax(6rem, 1fr) [center-start]
repeat(8, [col-start] minmax(min-content, 20rem) [col-end]) [center-end]
minmax(6rem, 1fr) [full-end];
}
// Content Layout
.cont2 {
grid-column: center-start / center-end;
margin: 10rem 0;
padding: 5rem;
grid-row: 3 / 4;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); //responsive layout
grid-gap: 4rem;
&__content {
align-self: center;
margin-left: 2rem;
font-size: 2rem;
&--p-2 {
margin-top: 3rem;
margin-bottom: 3rem;
}
}
&__img {
width: 100%;
}
}
.bg {
//width: 100vw;
//grid-column: full-start / full-end;
background-color: rgb(245, 245, 245);
//I've tried more than the commented out lines, but I've been trying it for a little bit tonight and forgot - sorry
}
I want the background color of .bg to bleed across the entire page, while keeping the integrity of the content within the 8 center columns.
Thanks in advance and let me know if I need to provide anymore info.
I got a problem with CSS Grid (I just started learning it). When I type the values of my grid-template-rows: in em, it works perfectly. But if I use percentage, all rows are all same height. I used to give them: 10% 80% 10% for: header, main, footer, but for some reason they are all same big. It makes no different if I change the Wrapper height(grid container element) from % to em or whatsoever. Here's my code:
#Wrapper {
display: grid;
grid-template-columns: 20% 60% 20%;
grid-template-rows: 10% 80% 10%;
min-height: 20em;
grid-template-areas:
"header header header"
"main main main"
"footer footer footer"
}
header {
background-color: #593093;
grid-area: header;
}
main {
background-color: #2AABBB;
grid-area: main;
}
footer {
background-color: #2F6692;
grid-area: footer;
}
h3 {
margin: 0;
}
<div id="Wrapper">
<header>
<h3>Header</h3>
</header>
<main>
<h3>Main</h3>
</main>
<footer>
<h3>Footer</h3>
</footer>
</div>
It is because your #Wrapper doesn't have a specified height or parent height. You can't use % as unit when the parent's height is not specified. Height in em is working since em is a absolute unit relative to parent px.
Define the height of the #Wrapper will be good to go.
#Wrapper{
height: 500px;
}
https://codepen.io/anon/pen/KrMwQM