I have the following HTML code:
<body>
<div id="id1" style="width: 100vw; height: 100vh; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr; background-color: khaki;">
<div id="id2" style="width: 100%; height: 100%; grid-row: 1; grid-column: 1;">
<div id="id3" style="width: 5000px; height: 3000px; background: dodgerblue"></div>
</div>
<div id="id4"style="width: 100%; height: 100%; grid-row: 1; grid-column: 2;"></div>
</div>
</body>
In my case "id1" div has size 1860px X 1340px. I expect "id2" and "id4" would both have 930px X 1340px size, and "id2" would have scrollbars because "id3" has greater size. In reality I get "id2" has 5000px X 3000px size, "id4" has 0px X 3000px size, and scrollbars appear in "id1", not "id2". If I remove "id3", "id2" and "id4" has expected sizes. How to make inserting "id3" not change the size of "id2" and "id3", but only lead to the appearance of scrollbars in "id2"?
This is simplified sample. In real life the size of "id1" is not known beforehand, so I cannot use 50vw X 100vh size for "id2" and "id4".
I dont understand the body of your question, but I do understand "forbid div enlarge its parents", yes, sometimes a div is bigger than its parent, there are ways to fix this:
Overflow Hidden Solution
<div id="parent" style="overflow:hidden">
<div id="child">
</div>
</div>
so you put the overflow hidden style on your parent, the child is still big but the only part of the child that you will be seen is the part that is within the parent's view box, the rest of the child is hidden. The attribute is on id2
<!DOCTYPE html>
<html>
<head >
<title>Title of the document</title>
</head>
<body>
<div id="id1" style="width: 100vw; height: 100vh; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr; background-color: khaki;">
<div id="id2" style="overflow:hidden;width: 100%; height: 100%; grid-row: 1; grid-column: 1;">
<div id="id3" style="width: 5000px; height: 3000px; background: dodgerblue"></div>
</div>
<div id="id4"style="width: 100%; height: 100%; grid-row: 1; grid-column: 2;"></div>
</div>
</body>
</html>
Overflow Scroll
This solution is like the one above but allows you to scroll to see the rest of the child element. I added the attribute to id2.
Here is the output of the code::
<!DOCTYPE html>
<html>
<head >
<title>Title of the document</title>
</head>
<body>
<div id="id1" style="width: 100vw; height: 100vh; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr; background-color: khaki;">
<div id="id2" style="overflow:scroll;width: 100%; height: 100%; grid-row: 1; grid-column: 1;">
<div id="id3" style="width: 5000px; height: 3000px; background: dodgerblue"></div>
</div>
<div id="id4"style="width: 100%; height: 100%; grid-row: 1; grid-column: 2;"></div>
</div>
</body>
</html>
Summary
You have to look into the overflow attribute, it gives you a lot of options on how to deal with children that are larger than their parents. If this does not answer your question, comment below with a more specific question or edit your question.
Related
I was trying to use the code below, but it did not work. I wanted to use the grid to define the whole webpage layout on every page I make. It seems like it is not that simple, because it seems like the grid accepts only a simpler flow of elements like this one:
The layout that the grid won't accept:
header just row one and column one
"right div element" row 2/3 and column 2/3
that is what I wanted.
I wanted to achieve that with this code:
<html>
<head>
<style>
body,
html {
margin: 0;
height: 100%;
width: 100%;
}
.main {
width: 100%;
height: 100%;
display: grid;
grid-template-rows: 120px 1fr 120px;
grid-template-columns: 200px 1fr auto;
}
.main footer {
grid-column: 1/3;
grid-row-start: 3;
background: #949994;
}
.main .header {
grid-column-start: 1;
grid-row-start: 1;
background: #034f84;
}
.main .right {
grid-row: 1/2;
grid-column: 2/3;
text-align: center;
background-color: aquamarine;
}
</style>
</head>
<body>
<div class="main">
<header>
</header>
<div class="right">
</div>
<footer>
</footer>
</div>
</body>
</html>
I got a problem with my grid. Doing it for the first time, so sorry for that beginner question.
What I want to achieve is shown in this image (black borders):
Unfortunately, I already got stuck on my first line of code:
body {
display: grid;
grid-template-columns: 10% auto 10% 10% 10%;
grid-template-rows: 60px auto; /*Isn't it recognizing my second row?*/
}
.temp {
background-color: black;
grid-column: 1 / 2;
grid-row: 2 / 3;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Max S. Rodenkirchen - Sinn Sehen - FH AC 2022 - bei Eva Vitting</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class = "menu">
</div>
<div class = "temp">
</div>
<div class = "draw">
</div>
<div class = "label">
</div>
<div class = "slider">
</div>
<div class = "check">
</div>
</body>
</html>
The temp class should be on the left-hand side in the second row.
Another question I have is probably a bit more advanced.
The square area is going to be a P5 canvas that is always squared and should always stay in full grid row height.
I was wondering if I need to code something like this instead:
grid-template-columns: auto 60% auto auto auto;
But I am pretty sure I am missing something here.
Hope for some help :) This is going to be for a university project.
Max
It seems easier to take the top menu out of the grid as its dimensions don't seem to be directly related to the rest of the elements.
By contrast the big square looks as though it is 8 times the width of the narrower columns.
The big square can be made to take the same height as its width by giving it aspect-ratio: 1 / 1;
So we can define a one row grid with 4 columns at 1fr and the square at 8fr.
To make it easy for it to be centered this snippet puts it inside containers which have flex.
* {
margin: 0;
padding: 0;
}
body {
width: 100vw;
}
.menu {
width: 100%;
height: 60px;
}
.outer {
display: flex;
justify-content: center;
margin-top: 1vw;
}
.container {
width: 95%;
display: grid;
grid-template-columns: 1fr 8fr 1fr 1fr 1fr;
grid-template-rows: 1fr;
gap: 1vw;
}
.menu,
.container div {
border: 1px solid black;
box-sizing: border-box;
}
.temp {
grid-row: 1 / 2;
}
.draw {
grid-column: 2 / 3;
aspect-ratio: 1 / 1;
}
.label {
grid-column: 3 / 4;
}
.slider {
grid-column: 4 / 5;
}
.check {
grid-column: 5 / 6;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Max S. Rodenkirchen - Sinn Sehen - FH AC 2022 - bei Eva Vitting</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="menu">
</div>
<div class="outer">
<div class="container">
<div class="temp">
</div>
<div class="draw">
</div>
<div class="label">
</div>
<div class="slider">
</div>
<div class="check">
</div>
</div>
</div>
</body>
</html>
Your second row is there and the .temp div is place in that row. It's just that because the .temp div has no content and the second row has a height of auto that row and the .temp div inside it have zero height and so are not visible. You can see what is going on more easily by adding outlines and minimum height:
body {
display: grid;
grid-template-columns: 10% auto 10% 10% 10%;
grid-template-rows: 60px auto;
}
div {
outline: 1px solid red;
min-height: 20px;
}
.temp {
background-color: black;
grid-column: 1 / 2;
grid-row: 2 / 3;
}
<div class="menu">
</div>
<div class="temp">
</div>
<div class="draw">
</div>
<div class="label">
</div>
<div class="slider">
</div>
<div class="check">
</div>
I have five rows in a grid layout.
There is a header row at the top.
I want the content row to fill everything it can of the available space.
I want the footer row to be at the bottom.
Between the header, content and footer rows I have two rows which just adds height spacing at 15px.
Here is HTML-code:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body class="body">
<div class="headerRow">
<div>Title</div>
<div>Fill</div>
<div>Image</div>
</div>
<div style="height: 15px;"></div>
<div>
content
</div>
<div style="height: 15px"></div>
<div class="footerRow">
<div>foo</div>
<div>bar</div>
</div>
</body>
</html>
Here is my CSS-code:
.body {
margin: 15px;
background: lime;
display: grid;
grid-template-rows: auto auto 1fr auto auto;
}
.headerRow {
display: grid;
grid-template-columns: auto 1fr auto;
background-color: #2196F3;
}
.footerRow {
display: grid;
grid-template-columns: auto auto;
background-color: red;
}
I got my "headerRow" to show three columns with the middle column to fill every available space with this line in the CSS:
grid-template-columns: auto 1fr auto;
So I tried this line in the .body-block in my CSS:
grid-template-rows: auto auto 1fr auto auto;
But that didn't work :'(
What is the problem?
Maybe like this:
html, body {
margin: 0;
padding: 0;
height: 100%;
}
.container {
margin: 15px;
background: lime;
display: grid;
grid-row-gap: 15px;
align-content: space-between;
height: 100%;
}
.headerRow {
display: grid;
grid-template-columns: auto 1fr auto;
background-color: #2196F3;
justify-items: center;
}
.footerRow {
display: grid;
grid-template-columns: auto auto;
background-color: red;
justify-content: space-between;
}
<!DOCTYPE html>
<html lang="en">
<div class="container">
<head>
<title>App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body class="body">
<div class="headerRow">
<div>Title</div>
<div>Fill</div>
<div>Image</div>
</div>
<div>
content
</div>
<div class="footerRow">
<div>foo</div>
<div>bar</div>
</div>
</div>
</body>
</html>
Why not use hr tag for adding space instead of another rows. Also if you want to make the three columns inside headerRow, Try adding float : left or adding columns from bootstrap would solve your problem.
I have some follow up questions after trying #Nikola Pavicevic solution:
Question 1:
In the html, body CSS-block the height: 100% seems to do the trick for me.But it makes the page in my web browser to have a vertical scrollbar.This scrollbar seems to be needed to show the "footer"-row.Is there anyway to decrease the height of the content row so the header row and footer row is always displayed?
Question 2:
The "content-row" seems to not fill all space available in the page.
I can see this by putting a background in the "content-row".
Is there a way to make sure the "content-row" fills all available space?
But keeps the "header-row" and "footer-row" visible.
Updated HTML:
<!DOCTYPE html>
<html lang="en">
<div class="container">
<head>
<title>App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body class="body">
<div class="headerRow">
<div>Title</div>
<div>Fill</div>
<div>Image</div>
</div>
<div class="spacerRow"></div>
<div class="contentRow">
content
</div>
<div class="spacerRow"></div>
<div class="footerRow">
<div>foo</div>
<div>bar</div>
</div>
</div>
</body>
</html>
Updated CSS
html, body {
margin: 0;
padding: 0;
height: 100%;
}
.container {
margin: 15px;
background: lime;
display: grid;
align-content: space-between;
height: 100%;
}
.headerRow {
display: grid;
grid-template-columns: auto 1fr auto;
background-color: #2196F3;
justify-items: center;
}
.footerRow {
display: grid;
grid-template-columns: auto auto;
background-color: red;
justify-content: space-between;
}
.spacerRow {
height: 15px;
background-color: yellow;
}
.contentRow {
background-color: purple;
}
I have a CSS grid, but I'm finding that the grid rows are not all fitting onto the page - instead, they're causing an overflow. How can I resize the grid rows so that they don't overflow the page? I thought the 1fr value was supposed to do this, but it doesn't seem to be working in my code.
I've had a look at Prevent content from expanding grid items and tried the suggested answers there (such as changing grid-template-rows: repeat(5, 1fr) to grid-template-rows: repeat(5, minmax(0, 1fr)); but to no avail.
I've tried adding height: 100% to the grid and it's container, but it is still overflowing.
JsFiddle https://jsfiddle.net/4g9b2qkL/
body,
html {
margin: 0;
height: 100%;
}
#container {
display: grid;
grid-template-columns: 1fr 5fr;
height: 100%;
}
#left {
grid-column: 1 / 2;
background: lightblue;
height: 100%;
}
#right {
grid-column: 2 / 3;
height: 100%;
}
#results {
display: grid;
grid-template-rows: repeat(5, 1fr);
height: 100%;
}
img {
max-height: 100%;
max-width: 100%;
}
<div id="container">
<div id="left">
<p>
Some stuff on the left....
</p>
</div>
<div id="right">
<h1>
Title
</h1>
<div id="results">
<div class="result">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/62/Paracas_National_Reserve%2C_Ica%2C_Peru-3April2011.jpg" />
</div>
<div class="result">
Result 2
</div>
<div class="result">
Result 3
</div>
</div>
</div>
</div>
A few things to consider:
missing height reference
Using a percentage value to set the height of the img is problematic because there is no defined height on the container. Generally speaking, percentage heights should have a height reference on the parent for reliable rendering. Your declarations may or may not be ignored / misinterpreted.
See: Working with the CSS height property and percentage values
height: 100%
Setting the #results element to height: 100% is problematic, if you want to prevent a vertical overflow, because it doesn't factor in the height of the sibling (the h1).
height: 100% + height of h1 title > height of container (resulting in an overflow)
use a flexible height instead
Instead of using a percentage height, set a more flexible height, such as flex-grow. This tells the container to simply consume remaining space.
override the minimum height default
Grid and flex items are set by default to stop shrinking at the size of their content. Override that setting with min-height: 0.
See: Why don't flex items shrink past content size?
cross browser compatibility
Chrome can do the layout with less code (than posted below). It makes more assumptions about an author's intentions. Firefox, Edge and Safari assume less, so require more rules.
#container {
display: grid;
grid-template-columns: 1fr 5fr;
height: 100vh;
}
#left {
background: lightblue;
}
#right {
display: flex;
flex-direction: column;
height: 100vh;
}
#results {
flex-grow: 1;
min-height: 0;
display: grid;
grid-template-rows: repeat(5, 1fr);
}
.result {
min-height: 0;
}
img {
max-width: 100%;
max-height: 100%;
}
body {
margin: 0;
}
<div id="container">
<div id="left">
<p>Some stuff on the left....</p>
</div>
<div id="right">
<h1>Title</h1>
<div id="results">
<div class="result">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/62/Paracas_National_Reserve%2C_Ica%2C_Peru-3April2011.jpg" />
</div>
<div class="result">Result 2</div>
<div class="result">Result 3</div>
</div>
</div>
</div>
You need to consider min-height:0 in different places and make some adjustment like below:
body,
html {
margin: 0;
height: 100%;
}
#container {
display: grid;
grid-template-columns: 1fr 5fr;
height: 100%;
}
#left {
grid-column: 1 / 2;
background: lightblue;
/*height: 100%; removed */
}
#right {
grid-column: 2 / 3;
/*height: 100%; removed */
min-height:0; /* here */
/* added */
display:flex;
flex-direction:column;
/**/
}
#results {
display: grid;
grid-template-rows: repeat(5, 1fr);
/*height: 100%; removed */
flex-grow:1; /* added */
min-height:0 /* here */
}
.result {
min-height:0 /* here */
}
img {
max-height: 100%;
max-width: 100%;
}
<div id="container">
<div id="left">
<p>
Some stuff on the left....
</p>
</div>
<div id="right">
<h1>
Title
</h1>
<div id="results">
<div class="result">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/62/Paracas_National_Reserve%2C_Ica%2C_Peru-3April2011.jpg" />
</div>
<div class="result">
Result 2
</div>
<div class="result">
Result 3
</div>
</div>
</div>
</div>
I have the following grid which I want to span for exactly the height of the screen - not less, not more. In the grid, I have a fixed header (one), a fixed footer (three) and a scrollable content (two)
.grid-container {
display: grid;
grid-template-areas:
"one"
"two"
"three"
;
grid-template-rows: 33px 1fr 34px;
height: 100vh;
}
What happens is that if the content inside two gets too large, the height of the entire grid is now larger than the viewport. As a result, my footer gets pushed down, while I would like instead to scroll the content and keep the footer where it is.
I know I can achieve what I want with position: fixed, but this is a trimmed-down example of a more complex grid. Any help is appreciated, I prefer to keep the grid approach if at all possible. I put together a fiddle for your convenience. Thank you!
https://jsfiddle.net/x6stfc01/1/
HTML For your convenience
<div class="grid-container">
<div class="one"></div>
<div class="two">
Start of Content
<div style="height: 5000px"></div>
End of Content
</div>
<div class="three"></div>
</div>
You could just add overflow-y: scroll to the two item or overflow-y: auto (even better)
body {
margin: 0;
}
.grid-container {
display: grid;
grid-template-areas: "one" "two" "three";
grid-template-rows: 33px 1fr 34px;
height: 100vh;
}
.one {
grid-area: one;
background-color: blue;
}
.two {
grid-area: two;
background-color: yellow;
overflow-y: scroll;
}
.three {
grid-area: three;
background-color: red;
}
<html>
<head>
</head>
<body>
<div class="grid-container">
<div class="one"></div>
<div class="two">
Start of Content
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> End of Content
</div>
<div class="three"></div>
</div>
</body>
</html>