Grid row to fill available content of page - html

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;
}

Related

How to create a flowchart in CSS

I am trying to put together a diagram in CSS of a flow chart. I have attached below a picture. Is there a simple way to do this? I've been Googling around quite a bit looking for examples, but I don't know what to call this.
Can you please let me know how to do this? Or if this is something common, what I can Google to find more information.
By using CSS Flex you could achieve something like:
body {font: 16px/1.4 sans-serif;}
.chart-row,
.chart-col {
display: flex;
gap: 1em;
}
.chart-row {
flex-direction: row;
}
.chart-col {
flex-direction: column;
}
.chart-pill,
.chart-rect{
padding: 1em;
text-align: center;
border: 2px solid #999;
}
.chart-pill {
flex: 1;
border-radius: 1em;
border-style: dashed;
}
.chart-rect{
flex: 0;
margin: auto 0;
background: #eee;
}
.chart-line-h {
height: 2px;
min-width: 3em;
background: #999;
margin: auto -1em;
}
<div class="chart-row">
<div class="chart-pill chart-col">
<div class="chart-rect">alpha</div>
</div>
<div class="chart-line-h"></div>
<div class="chart-pill chart-col">
<div class="chart-rect">beta</div>
<div class="chart-rect">gamma</div>
<div class="chart-rect">delta</div>
</div>
<div class="chart-line-h"></div>
<div class="chart-pill chart-col">
<div class="chart-rect">gamma</div>
</div>
</div>
I'll just add an answer because I can't write any comments yet, although I'm not new at CSS...
Yes, you can use Flexbox but I will also add CSS Grid, as the combination of both can give you more flexibility if you're planning on making bigger charts...
Once you get it working, it's pretty easy to use...
Copy and paste this code in your code editor and display it in your browser.
( if you use VSCode you can use the liveServer extension)
Then go to the dev tools inside your browser (Ctrl+Shift+i) and click the icon to select an element (the one on top at the very left hand side).
Then, inside the first div, you will see a label with the word grid, click it and you'll see the grid on your screen.
Finally, you just have to fill the rows and columns with the figures as in one of those old battleship games, or a 2D Cartesian Coordinate System.
Keep in mind that when placing your items on the Grid, it's better to use the lines instead of the areas of the rows and columns, as it's much easier to understand it this way.
So for instance, in this case, connector1 goes from vertical line 9 to vertical line 10, or the first figure fills the space between line 5 and line 9, and so on.
Hope it helps!
By the way, I changed colours as it's easier for the explanation..
HTML :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Document</title>
</head>
<body>
<!-- GRID FLOWCHART -->
<div class="flowchart">
<!-- FIRST FIGURE -->
<div class="set" id="set1">
<div class="box"><p>alpha</p></div>
</div>
<!-- FIRST CONNECTOR -->
<div class="connector" id="connector1"></div>
<!-- SECOND FIGURE -->
<div class="set" id="set2">
<div class="box"><p>beta</p></div>
<div class="box"><p>gamma</p></div>
<div class="box"><p>delta</p></div>
</div>
<!-- SECOND CONNECTOR -->
<div class="connector" id="connector2"></div>
<!-- THIRD FIGURE -->
<div class="set" id="set3">
<div class="box"><p>gamma</p></div>
</div>
</div>
</body>
</html>
CSS :
body {
width: 100vw;
height: 100vh;
background-color: #d3d3d3;
}
/* ****** GENERIC SHAPES : ********** */
.flowchart {
display: grid;
grid-template-columns: repeat(24, 1fr);
grid-template-rows: repeat(12, 1fr);
width: fit-content;
height: fit-content;
grid-gap: 2px;
}
.set {
min-width: 100px;
min-height: 100px;
border: 2px dashed blue;
border-radius: 15px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box {
width: 80%;
height: 15%;
background-color: rgb(255, 255, 255);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 4%;
padding: 6%;
border: 1px solid black;
/* border-radius: 5px; */
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 0.9em;
}
.connector {
width: 120%;
max-height: 3px;
background-color: black;
transform: translateX(-6%);
}
/* ************* FIGURES : ************* */
#set1 {
grid-column: 5/9;
grid-row: 5/12;
}
#set2 {
grid-column: 10/14;
grid-row: 5/12;
}
#set3 {
grid-column:15/19;
grid-row: 5/12;
}
/* ******** CONNECTORS : *********** */
#connector1 {
grid-column: 9/10;
grid-row: 8/9;
}
#connector2 {
grid-column: 14/15;
grid-row: 8/9;
}

CSS - Grid row not recognized

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>

Issue with CSS Grid: Background IMG Positioning and width of topContainer extending screen slightly

So, I'm in the process of learning CSS Grid and I'm running into a couple of issues here. I've been messing around in the inspection panel and removing some CSS every now and then and I can't come to a solution.
First, the background-image needs to be a bit lower, but the container doesn't -- so I basically need a higher view of the photo that's shown, so it's not showing the center of the photo only if that makes sense.
Second, any time I remove position: absolute; from .bg-img the causes the second screenshot to occur, shrinking my grid...I need the grid to preserve its division of the entire page into grid-template-columns: 1fr 4fr 1fr; and not adjust to the top left corner of the page as it does.
Any ideas here/concepts I'm missing? Learning web-dev is awesome so far, but fixing issues when you don't know what's wrong is rough! haha.
Screenshot of Page:
Removing the css for position: absolute on .bg-img{} causes the below view:
Screenshot of Page post-removal:
Code:
body,
html {
background-color: black;
}
/* bg image styline */
.bg-img {
position: absolute;
background-image: url(/Practice_Site-main/imgs/nature.jpg);
background-repeat: no-repeat;
background-position: center;
outline: solid white;
border-radius: 60px;
width: 100%;
height: 50%;
filter: brightness(0.7);
}
/* top of site heading and navbar */
#mainGrid {
display: grid;
grid-template-columns: 1fr 4fr 1fr;
grid-template-rows: repeat(5, 5fr);
}
#topContainer {
display: grid;
grid-template-columns: 1fr 4fr 1fr;
position: relative;
grid-column: 2;
grid-row: 2;
gap: 10px;
background-color: #09cc43;
border-radius: 40px;
outline: solid black;
opacity: 0.85;
filter: brightness(1) !important;
justify-content: center;
}
#siteHeader {
grid-column: 2;
justify-self: center;
text-align: center;
}
nav {
grid-column: 2;
grid-row: 2;
justify-items: center;
}
#primary-navigation {
grid-column: 2;
list-style-type: none;
justify-items: center;
}
ul {
grid-column: 2;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TESTER</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="mainGrid">
<div class="bg-img">
<div id="topContainer">
<h1 id="siteHeader">Testing Header</h1>
<nav>
<ul id="primary-navigation" class="primary-navigation">
<li class="active">
<span aria-hidden="true"></span>Home
</li>
<li>
<a href="photos.html">
<span aria-hidden="true"></span>Photos</a>
</li>
<li>
<span aria-hidden="true"></span>About
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="homeFolio"></div>
</body>
</html>
Because position: absolute; the width and height of the bg-img element is determined by the parent element with position: relative; set, if the parent element does not set position: relative, the width and height of the bg-img will be determined according to the body element, This is what you delete position: absolute cause a width and height error

Breakout Sidebar Elements via CSS Grid

I am trying to achieve a layout with multiple elements of different height stacked on mobile screens and some elements forming a sidebar for desktop, roughly looking like this:
My first idea was to achieve it via CSS grid, defining one row with two columns and then assigning the grid-area depending on the class (orange vs gray):
Codepen
.layout {
display: grid;
max-width: 860px;
margin: 0 auto;
gap: 20px;
}
#media(min-width: 860px) {
.layout {
grid-template-areas: 'main sidebar';
grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: main;
}
Problem: as multiple sidebar elements now occupy the same grid cell, they overlap instead of just flow on top of each other. I've been trying to wrap my head around alternative solutions for a few days now, but I couldn't find any so far that did not involve reordering the dom with JavaScript. Am I missing the obvious?
EDIT
Flexbox as stated in the answers does not solve this problem (if the position of elements within the list would be known upfront maybe, but this is not the case). Some elements go in the sidebar, some go in the main bar while having a fixed order in the mobile layout.
Use Flexbox, then you can easily do this.
Refer following code,
.layout {
display: flex;
flex-wrap: wrap;
max-width: 860px;
margin: 0 auto;
gap: 20px;
}
set correct order of div (containers) as you need, (the following code is sample one)
<div id="main">
<div style="background-color:coral;" id="myRedDIV"></div>
<div style="background-color:lightblue;" id="myBlueDIV"></div>
<div style="background-color:lightgreen;" id="myGreenDIV"></div>
<div style="background-color:pink;" id="myPinkDIV"></div>
</div>
#main {
width: 100%;
height: 150px;
border: 1px solid #c3c3c3;
display: flex;
flex-wrap: wrap;
}
#main div {
width: 70px;
height: 70px;
}
/* Standard syntax */
div#myRedDIV {order: 1;}
div#myBlueDIV {order: 4;}
div#myGreenDIV {order: 3;}
div#myPinkDIV {order: 2;}
Refer following links for more about Order in Flexbox
Link1 --> About Flexbox Order
Link2 --> About Flexbox Order
Why don't you try with flexbox. you can do it using display:flex, for more about the flex refer below sample.
<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
display: flex;
flex-wrap: nowrap;
background-color: DodgerBlue;
}
.flex-container > div {
background-color: #f1f1f1;
width: 100px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
}
</style>
</head>
<body>
<h1>Flexible Boxes</h1>
<div class="flex-container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
<p>Try to resize the browser window.</p>
<p>A container with "flex-wrap: nowrap;" will never wrap its items.</p>
<p><strong>Note:</strong> Flexbox is not supported in Internet Explorer 10 or earlier versions.</p>
</body>
</html>
This might not be the answer to your question! (cause I've changed the grid layout into FlexBox)
In this example I'm changing flex-direction via screen breakouts.
More Information on CSS Flex box Direction
Code:
* {
border: 1px solid coral;
padding: 12px;
margin: 12px;
}
.layout {
display: flex;
flex-direction: column;
align-items: center;
}
.layout>* {
display: flex;
flex-direction: row;
}
.sidebar {
background-color: yellow;
}
.content {
background-color: grey;
}
#media(max-width: 860px) {
.layout {
display: flex;
flex-direction: column;
align-items: center;
}
.layout>* {
display: flex;
flex-direction: column;
}
.sidebar {
background-color: yellow;
}
.content {
background-color: grey;
}
.content {
background-color: green;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="layout">
<div>
<div class="content big">
Here's some text
</div>
<div class="sidebar small">
Sidebar Item
</div>
</div>
<div>
<div class="content big">
More Text
</div>
<div class="sidebar small">
another sidebar Item
</div>
</div>
</div>
</body>
</html>

Viewport is changing zoom when Flexbox container is running out of space

My page starts to change zoom and layout gets slightly messed up when I have a hardcoded width on items located in a Flexbox container (make a very narrow Chrome Devtools responsive window). The problem starts when I make my viewing area narrower than the 300px. Unfortunately, you can't see this problem when running this inside an iframe on jsfiddle - it has to be ran "on it's own", my html block needs to be THE top html block.
Here's the jsfiddle for reference still:
https://jsfiddle.net/elijahww/9e1u7ptr/
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#productShowcaseContainer {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
.contentContainer {
display: flex;
flex: 1;
}
#productShowcaseTitle {
height: 100px;
background-color: antiquewhite;
}
#productShowcaseThumbnailContainer {
flex: 1;
background-color: darkseagreen;
}
</style>
</head>
<body style="margin: 0;">
<div id="productShowcaseContainer">
<div id="productShowcaseTitle"></div>
<div class="contentContainer">
<div id="productShowcaseThumbnailContainer" style="padding: 10px;">
<input style="width:300px;">
</div>
</div>
</div>
</body></html>
I don't know how to make this work.
here is a gif:
This might be happening because you have hard-coded width of input field as 300px and trying to zoom screen width beyond this.
If you really want to have responsive layout then you should be using flex-layout properly and set flex-basis, flex-grow and flex-shrink property of each layout element.
These properties are responsible for handling responsive behaviour of flex-elements.
To Read more about flex layout follow this link Flex tutorial
One option is to give some parent container overflow-x: auto
body {
background-color: #3d5d6a;
}
#container {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
.main-content-container {
display: flex;
flex: 1;
}
#top-header-container {
padding: 10px;
height: 100px;
background-color: antiquewhite;
/*align-content: stretch;*/
display: flex;
justify-content: stretch;
}
#main-content-inner {
flex: 1;
background-color: darkseagreen;
}
.responsive-table {
overflow-x: auto;
}
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="margin: 0;">
<div id="container">
<div id="top-header-container">
<div class="responsive-table">
<input style="width:400px;" value="hard coded to 400px">
</div>
</div>
<div class="main-content-container">
<div id="main-content-inner" style="padding: 10px;">
test
</div>
</div>
</div>
</body></html>