Css-Grid / Flexbox aside and main not growing 100% - css

I am creating a css-grid / flexbox template and it's all working as it should.
It has a header, aside, main and footer.
I just need the asign and main row to stretch so it takes the whole page minus the header and footer height.
I want to do this without having to use the "vh"
Here is the full current code:
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 30% auto;
grid-template-rows: auto 1fr auto;
grid-template-areas: "header header"
"sidebar main"
"footer footer"
}
header,
aside,
main,
footer {
padding: 16px;
text-align: center;
}
header {
background: purple;
grid-area: header;
}
aside {
background: blue;
grid-area: sidebar;
}
main {
background: green;
grid-area: main;
}
footer {
background: orange;
grid-area: footer;
}
How can I get the asign and main to auto stretch?

You can use :root{} for that and calc() with variables to calculate the height. Sorry for re-coding your attempt, but I think it was better to start from zero to show you a new approach.
Try the following snippet
* {box-sizing: border-box;padding: 0;margin: 0}
:root{
--nav-height: 80px;
--footer-height: 80px;
}
.grid-container{
display: grid;
grid-template-columns: 30% 70%;
height:calc(100vh - var(--nav-height) - var(--footer-height));
}
.grid-item{
border:1px solid black;
padding:10px;
}
.nav{
width:100%;
height:var(--nav-height);
border:1px solid black;
padding:10px;
}
footer{
width:100%;
height:var(--footer-height);
border:1px solid black;
padding:10px;
}
<body>
<div class="nav">nav content</div>
<div class="grid-container">
<div class="grid-item">body content one</div>
<div class="grid-item">body content two</div>
</div>
<footer>footer content</footer>
</body>

In order to make it the correct browser height, the view height (vh) property would be required.
You could alternatively use a fixed pixel height, or make it relative to the width for a specific aspect ratio, but neither of these would be responsive to 100% browser height.
Is there any reason you don't want to use vh?

One way to do it strictly with flex-box would be to wrap both the aside and main in a div, and set flex property of the div to 1
<div class="container">
<aside>aside</aside>
<main>main</main>
</div>
.container {
display: flex;
flex: 1;
}
but in order for that to work you would probably have to make the entire body a flex-box
body {
display: flex;
flex-direction: column;
}

Related

Can a responsive page layout be achieved using css grid and flexbox without media queries?

I'm trying to achieve this layout (https://codepen.io/totkeks/pen/PowodPq) with a top section, main section and side section.
<div class="grid">
<div class="top">Top</div>
<div class="main">Main</div>
<div class="side">Side</div>
</div>
body {
padding: 0;
margin: 0;
}
.grid {
display: grid;
grid-gap: 3rem;
grid-template-columns: 22rem minmax(48rem, auto);
grid-auto-rows: auto;
padding: 3rem;
min-height: 100vh;
box-sizing: border-box;
border: 2px dotted black;
}
.top, .main, .side {
background-color: papayawhip;
}
.main {
grid-row: span 2;
}
#media screen and (max-width: 1200px) {
.grid {
grid-template-columns: 1fr;
}
}
When the page is smaller (< 1280px currently in CSS query) the three sections are stacked on top of each other, first top, then main, then side, all covering the full width.
When the page is wider, the top and side sections are fixed size on the left side and the main section is on the right side, growing as space becomes available.
Just a moment ago I found this Q&A Responsive layout without media query and while it goes in the right direction, it is not entirely what I'm trying to achieve.
I already spent two evenings with this idea and would like to find a solution or get a definitive "No, that's not possible with current CSS".
You could give a try with auto-fit, grid-colum, grid-row and use width + calc() to trick the wrapping . But you could find funny behaviors from a browser to anoter . (auto-flow is required ) However, mediaquerie is made for this, much cleaner and reliable.
body {
padding: 0;
margin: 0;
}
.grid {
display: grid;
grid-gap: 3rem;
margin: 1em;
border: solid;
grid-template-columns: repeat(auto-fit, minmax(22rem,auto));
grid-auto-rows: auto;
padding: 3rem;
min-height: calc(100vh - 2em);
box-sizing: border-box;
}
.top,
.main,
.side {
background-color: orange;
border:solid;
}
.top,
.side {
grid-column: 1;
width: 22rem;
min-width:100%;
}
.main {
grid-column: auto;
min-width: calc(100vw - 33rem);
grid-row: span 2;
}
<div class="grid">
<div class="top">Top</div>
<div class="main">Main</div>
<div class="side">Side</div>
</div>
My answer maybe yes for the fun only.

How to fix footer at the bottom of a component in react?

I'm trying to put a footer at the end of my homepage component. In my website, the overflow is made auto only for mobile view with a media query, so the scroll remains hidden for desktop view. I have used all the solutions I could find but nothing helps, the footer is perfectly aligned in desktop view at the bottom, but for mobile view, it is aligned at the end of the screen (not the page). I have no clue how to fix this.
website: https://shivamaima.netlify.com/
git: https://github.com/darwin619/portfolio
.homepage {
text-align: center;
width: 100%;
position:relative;
padding:0;
margin:0;
min-height:100vh;
top:0;
#media screen and (max-width: 600px) {
overflow: auto;
height: 100vh;
}
.footer {
position: absolute;
right: 0;
bottom: 0;
left: 0;
padding: 1rem;
text-align: center;
}
There's a couple solutions here. Instead of bottom: 0 use:
margin-top: 100vh;
This will set the footer at the bottom of the viewport height.
However, your page has quite a few layout issues, and this is really a band-aid. You should consider utilizing flexbox, min-height, or grid to create a sticky footer.
That being said, the solutions for this using react are what they would be in most any circumstance.
The following solutions are preferable because they are "true" dynamic sticky footers. Meaning, the footer stays at the bottom until the main content extends beyond that area, at which point the footer will begin adjusting its position downward:
The min-height Solution
nav {
height: 40px;
padding: 10px;
background: lightblue;
}
main {
padding: 20px;
background: purple;
min-height: calc(100vh - 170px);
}
footer {
background: magenta;
padding: 10px;
height: 50px;
}
<html>
<body>
<nav>
Navigation
</nav>
<main>
Page content
</main>
<footer>
Footer that stays put
</footer>
</body>
</html>
As can be seen, we set the minimum height of the content to 100vh minus whatever the combined height (plus padding) happens to be of your nav and content containers.
This results in a footer that sticks, along with the ability to drop further if the content exceeds the min-height value.
The same effect can be accomplished using flexbox, which is arguably a more dynamic solution. However, it comes at the expense of an extra container element. We could apply flex to body, but that is rarely a proper solution:
The flex box solution
.container {
display: flex;
min-height: calc(100vh - 40px);
flex-direction: column;
}
nav {
height: 40px;
padding: 10px;
background: lightblue;
}
main {
padding: 20px;
background: purple;
flex: 1;
}
footer {
background: magenta;
padding: 10px;
height: 50px;
}
<body>
// Use className instead of class for react (jsx)
<div class="container">
<nav>
Navigation
</nav>
<main>
Main Content Area
</main>
<footer>
Footer that stays put
</footer>
</div>
</body>
The CSS Grid Solution with min-height
.container {
display: grid;
grid-gap: 1em 0;
grid: auto auto 1fr / 10vw 1fr 10vw;
margin: 0;
min-height: calc(100vh - 40px);
}
nav {
background-color: lightblue;
grid-column: 2;
padding: 20px;
}
main {
background-color: purple;
display: grid;
grid-column: 2;
padding: 20px;
}
footer {
background-color: magenta;
align-self: end;
grid-column: 2;
padding: 20px;
}
// Use className instead of class for react (jsx)
<div class="container">
<nav>
Navigation
</nav>
<main>
Main Content Area
</main>
<footer>
Footer that stays put
</footer>
</div>
Note: Change class to className if you're working on a react project.

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 Layout Gap Box Sizing

I have a CSS grid that occupies 100% width and 100% height of a window (the body element has display: grid;). The grid has row and column templates and elements which occupy 100% of their allocated space. However, when I add a grid-gap to the grid, it makes the grid too large for the window, forcing scrollbars to appear. How can I stop the grid-gap from adding to the dimensions of the grid - similar to how box-sizing: border-box; stops padding from adding to the dimensions of an element? Instead, I want the gaps to shrink the cells of the grid.
Thanks.
When you use "fr" it works.
Example:
HTML:
<section>
<article class="a">A</article>
<article class="b">B</article>
<article class="c">C</article>
<article class="d">D</article>
</section>
SCSS:
section {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-flow: column;
grid-gap: 20px;
border: 10px solid blue;
article {
background-color: tomato;
&.d {
grid-column: 2;
grid-row-start: 1;
grid-row-end: 4;
background-color: olive;
}
}
}
It works same as if you used box-sizing: border-box and padding as you can see in this demo. Height is set to 100vh and you can see that if you remove or add grid-gap there is no scrollbar, you just need to remove margin from body.
body {
margin: 0;
}
.grid {
display: grid;
height: 100vh;
grid-gap: 20px;
background: #FF7D7D;
grid-template-columns: 1fr 2fr; /* Use Fractions, don't use % or vw */
}
.grid > div {
background: black;
color: white;
}
div.a, div.d {
color: black;
background: white;
}
<div class="grid">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
<div class="d">D</div>
</div>
You could use view-port units:
vw (1% of window's width)
vh (1% of window's height)
* {
margin: 0;
padding: 0;
box-sizing: border-box;
height: 100%;
}
.first { height: 40vh; }
.hori { height: 10vh; }
.second { height: 50vh; }
div > div {
float: left;
}
.left { width: 40vw; }
.vert { width: 10vw }
.right { width: 50vw; }
.first .left,
.second .right {
background: #ccc;
}
.first .right,
.second .left {
background: #000;
}
<div class="first">
<div class="left"></div>
<div class="grid-break vert"></div>
<div class="right"></div>
</div>
<div class="grid-break hori"></div>
<div class="second">
<div class="left"></div>
<div class="grid-break vert"></div>
<div class="right"></div>
</div>

CSS Stick Footer to Bottom

Here is my code to stick the footer to bottom of the page:
#footer {
background-color: #0F2157;
width: 100%;
bottom: 0px;
min-height: 35px;
padding-top: 5px;
}
When I'm doing it with height it works perfectly fine, but when I'm trying to set the minimum height it leaves a little space under the footer. Any guess how to fix that?
First of all, the height of body, html and container (see element with class 'container') has to have height: 100%;
In this solution I have used flex box. It is supported by all modern browsers and IE11.
It's necessary to add the following properties to container:
display: flex;
flex-direction: column; /*the flex items are placed in column, by default it is in row*/
To move footer to bottom, just add to flex item
margin-top: auto; /* it grabs all free space between flex items and put it before this flex item */
html, body {
height: 100%;
}
.container {
height: 100%;
background-color: green;
display: flex;
flex-direction: column;
}
.header {
height: 20%;
background-color: yellow;
}
.content {
background-color: white;
}
.footer {
min-height: 20%;
background-color: blue;
margin-top: auto;
}
<div class="container">
<div class="header">Header</div>
<div class="content">It's content</div>
<div class="footer">Footer in bottom</div>
</div>
What about using Flexbox? It is supported by IE>=10.
To use that, you have to split your page at least in two separated elements: The "upper"-one (.content) with the whole content of your page and the footer.
The "upper"-one gets the value flex: 1, which is a shorthand for:
flex-grow: 1
flex-shrink: 1
flex-basis: auto
This means, that the "upper"-element could grow to the maximum, while the footer reserves only it's actually required space.
Code snippet
html {
height: 100%;
}
body {
min-height: 100%;
margin: 0;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
}
<!doctype html>
<html>
<head>
</head>
<body>
<div class="content"></div>
<footer class="footer">
Hey footer!
</footer>
</body>
</html>
You used min height 35 px. I think your content's height inside of footer is more than 35px. So check the margin or padding of all footer elements.
It will be better, if you can make a jsfiddle demo.
[SOLVED]
I found this to be working for my example:
#footer {
position: absolute;
bottom: 0;
width: 100%;
}

Resources