Getting header and footer hight via CSS - css

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>

Related

How to wrap element in CSS grid

With Flex, I can wrap using flex-wrap. I'm experimenting with CSS grid and want to wrap an element but can't find a way to do that. Is it possible?
Here is my code
.item1 {
grid-area: topic;
}
.item2 {
grid-area: user;
}
.item3 {
grid-area: bin;
}
.bin-grid {
display: grid;
grid-template-columns: 200px auto;
grid-template-areas: 'topic topic topic' 'user bin bin';
gap: 0;
padding-bottom: 15px;
margin-bottom: 20px;
}
<div class="bin-grid">
<div class="item1">Header</div>
<div class="item2">Left</div>
<div class="item3">Right</div>
</div>
I tried using grid-template-columns:200px auto; but that isn't wrapping the elements. I need item2 and item3 to wrap.
After a link that was posted by a SO user for the same issue, I tried using grid-template-columns:repeat(auto-fill, 186px) but the elements will not wrap in my case. Yet, I can see the example works just fine. I'm not sure why it won't work in my case.

How do you create a fullscreen layout

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>

Grid layout with search bar in header

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

CSS grid with fixed-width larger than content

I have a simple CSS grid, with one cell - an <img>. The grid has a fixed width of 100px and uses grid-auto-columns: 100%; to scale the image down to fit inside:
.grid {
display: grid;
width: 100px;
grid-auto-columns: 100%;
background-color: #844;
}
.grid > * {
grid-column: 1;
grid-row: 1;
}
<div class='grid'>
<img src='https://i.imgur.com/HAwaW3D.png' />
</div>
But for some reason, the grid's height remains as if the image was rendered at its original size, leaving this empty space after the cell:
And I cannot for the life of me find a way to avoid it.
Any ideas on how to make the grid's height match its contents in this scenario?
note: I'm testing in Firefox 56.2.5

Css - Width / Height 100% without dynamic amount of pixels

How to set the width of an element to take 100% the width of its parent minus an unknown width of sibling element.
index.html
<div class="main">
<div class="sidemenu">
...
</div>
<div class="contant">
...
</div>
</div>
style.css
.main
{
width: 100vw;
}
.sidemenu
{
width: X; /* this value is dymanic, it may change in runtime using JS */
}
.contant
{
width: ???; /* what do I put here? */
}
If the side-menu width was fixed I could of use calc(100% - X), but since the width is dynamic, how can I set the width to take the remaining width of the parent?
Can I achieve this using Css only (without JavaScript)?
You may use flexbox so there's no need to assign a specific width to the content area
e.g.
.main {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
.content { flex: 1; margin-left: 1rem; }
Codepen demo
I know this is an old post but this could also be done using css variables.
:root {
--dynamic-width: X;
}
.content {
width: CALC(100% - var(--dynamic-width));
}
See: https://jsfiddle.net/wzget15m/
the method you might look for is only possible using js otherwise you can't get the width of the element to calculate it with another.
Use display: flex in the main container:
.main {
display: flex;
}
.sidemenu {
width: X;
}
.contant {
width: 100%; /* what do I put here? */
}

Resources