Why relatively positioned element overlaps a sticky element? [duplicate] - css

This question already has answers here:
Why does position:relative; appear to change the z-index?
(2 answers)
One element's position is absolute, the other's position is relative, which one is the upper
(2 answers)
Why using absolute position causes the div to be on top?
(3 answers)
Closed 2 years ago.
Header has position: sticky, and is followed by some content.
When a following element has position: relative (e.g. Hero in the example below), it overlaps the sticky Header when the page is scrolled.
Why is this happening?
What's the idiomatic way to avoid the overlap?
Is defining a z-index necessary?
body {
margin: 0;
}
.container {
width: 200px;
background-color: #eee;
}
.header {
background-color: #ccc;
height: 40px;
line-height: 40px;
position: sticky;
top: 0;
}
.hero {
background-color: #ddd;
height: 60px;
line-height: 60px;
/* This causes the overlap */
position: relative;
}
<div class="container">
<div class="header">Header</div>
<div class="hero">Hero</div>
<p>
Sed augue lacus viverra vitae congue eu consequat ac. Diam sollicitudin tempor id eu nisl nunc mi. Massa massa ultricies mi quis hendrerit dolor magna eget est. Maecenas sed enim ut sem. Bibendum arcu vitae elementum curabitur vitae nunc. Diam vel quam
elementum pulvinar etiam non quam lacus. Lobortis mattis aliquam faucibus purus in massa tempor. Suspendisse sed nisi lacus sed viverra tellus in. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus et. Eget egestas purus
viverra accumsan in. Massa tempor nec feugiat nisl pretium fusce id. Egestas sed sed risus pretium quam vulputate dignissim. Magna sit amet purus gravida quis blandit turpis cursus in. Integer enim neque volutpat ac tincidunt vitae. Adipiscing commodo
elit at imperdiet dui accumsan sit. Magna ac placerat vestibulum lectus mauris ultrices. A diam maecenas sed enim ut sem. Ultrices eros in cursus turpis massa tincidunt dui. Est ullamcorper eget nulla facilisi etiam dignissim. Convallis tellus id
interdum velit laoreet id donec. Ullamcorper malesuada proin libero nunc consequat interdum varius.
</p>
</div>

You need to add z-index property in .header class if you define position:relative in bottom of any element so you can just remove position:relative from .here class or bottom element of header.
body {
margin: 0;
}
.container {
width: 200px;
background-color: #eee;
}
.header {
background-color: #ccc;
height: 40px;
line-height: 40px;
position: sticky;
top: 0;
z-index: 1;
}
.hero {
background-color: #ddd;
height: 60px;
line-height: 60px;
/* This causes the overlap */
position: relative;
}
<div class="container">
<div class="header">Header</div>
<div class="hero">Hero</div>
<p>
Sed augue lacus viverra vitae congue eu consequat ac. Diam sollicitudin tempor id eu nisl nunc mi. Massa massa ultricies mi quis hendrerit dolor magna eget est. Maecenas sed enim ut sem. Bibendum arcu vitae elementum curabitur vitae nunc. Diam vel quam
elementum pulvinar etiam non quam lacus. Lobortis mattis aliquam faucibus purus in massa tempor. Suspendisse sed nisi lacus sed viverra tellus in. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus et. Eget egestas purus
viverra accumsan in. Massa tempor nec feugiat nisl pretium fusce id. Egestas sed sed risus pretium quam vulputate dignissim. Magna sit amet purus gravida quis blandit turpis cursus in. Integer enim neque volutpat ac tincidunt vitae. Adipiscing commodo
elit at imperdiet dui accumsan sit. Magna ac placerat vestibulum lectus mauris ultrices. A diam maecenas sed enim ut sem. Ultrices eros in cursus turpis massa tincidunt dui. Est ullamcorper eget nulla facilisi etiam dignissim. Convallis tellus id
interdum velit laoreet id donec. Ullamcorper malesuada proin libero nunc consequat interdum varius.
</p>
</div>

Related

How do I make 2 overlapping row elements with the same parent have the same height in CSS, where the z-index differs?

I am looking to make the div with the background on the left and right hand side, fill up the height of its container or be the height of another div the container contains (the magenta one).
Below are is an image.
Here is a JS Fiddle with my working code with a preview.
<div class="outercontainer">
<div class="innercontainerback orangeborder"></div>
<div class="innercontainer padding1 magenta">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam convallis id tellus vitae ultrices. Phasellus elit leo, vulputate et malesuada ac, venenatis vel augue. Mauris maximus ex ac orci blandit auctor. Praesent lectus dolor, pretium vitae ultricies vel, accumsan a ante. Fusce blandit semper suscipit. Vivamus ultricies ipsum et finibus malesuada. Aliquam tempor, tellus in bibendum fringilla, nunc lacus posuere sem, nec elementum enim eros a massa. Maecenas eleifend elementum nisi accumsan luctus. Aenean ac tortor mollis, aliquam magna vel, aliquet sapien. Fusce purus quam, pulvinar quis enim nec, ornare luctus felis. Aliquam consectetur dapibus dictum. Morbi et ex eu risus euismod viverra sit amet sit amet augue. Nam mollis hendrerit tincidunt. Sed posuere suscipit ipsum id sagittis. Mauris quis sapien vitae mi tristique accumsan. Praesent cursus dui vehicula leo viverra venenatis.
</div>
</div>
And below is my CSS
html, body, .outercontainer, .innercontainerback { height: 100%; min-height: 100%; }
body {
margin: 0px;
padding: 0px;
font-family: Tahoma;
}
.outercontainer {
width: 100%;
}
.innercontainerback, .innercontainer { width: 400px; }
.magenta { background-color: magenta; }
.orangeborder { border: 5px solid orange; }
.innercontainerback {
/*margin-left: auto; margin-right: auto;*/
background-image: url('https://i.imgur.com/vvaALIn.png'), url('https://i.imgur.com/trZrIdu.png');
background-position: left, right;
background-repeat: repeat-y, repeat-y;
opacity: 0.88;
z-index: 1; position: absolute;
/* left: 50%; margin-left: -400px; */
top: 0px;
}
.innercontainer {
/* height: 100%; */
min-height: 100%;
/* margin-left: auto;
margin-right: auto; */
opacity: 1 !important;
position: relative; z-index: 0;
clear: both;
}
.padding1 {
padding-left: 90px; padding-right: 90px; box-sizing: border-box;
padding-top: 32px;
/*margin-top: 32px; */
}
How do I make 2 overlapping elements with the same parent have the same height in CSS of which both divs are not columns, and the z-index differs?
Remove height: 100% from outercontainer and add position:relative to outercontainer
html,
body,
.innercontainerback {
height: 100%;
min-height: 100%;
}
body {
margin: 0px;
padding: 0px;
font-family: Tahoma;
}
.outercontainer {
min-height: 100%;
position: relative;
}
.innercontainerback,
.innercontainer {
width: 400px;
}
.magenta {
background-color: magenta;
}
.orange {
background-color: orange;
}
.innercontainerback {
background-image: url('https://i.imgur.com/vvaALIn.png'), url('https://i.imgur.com/trZrIdu.png');
background-position: left, right;
background-repeat: repeat-y, repeat-y;
opacity: 0.88;
z-index: 1;
position: absolute;
top: 0px;
}
.innercontainer {
min-height: 100%;
opacity: 1 !important;
position: relative;
z-index: 0;
clear: both;
}
.padding1 {
padding-left: 90px;
padding-right: 90px;
box-sizing: border-box;
padding-top: 32px;
}
<div class="outercontainer">
<div class="innercontainerback orange"></div>
<div class="innercontainer padding1 magenta">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam convallis id tellus vitae ultrices. Phasellus elit leo, vulputate et malesuada ac, venenatis vel augue. Mauris maximus ex ac orci blandit auctor. Praesent lectus dolor, pretium vitae ultricies
vel, accumsan a ante. Fusce blandit semper suscipit. Vivamus ultricies ipsum et finibus malesuada. Aliquam tempor, tellus in bibendum fringilla, nunc lacus posuere sem, nec elementum enim eros a massa. Maecenas eleifend elementum nisi accumsan luctus.
Aenean ac tortor mollis, aliquam magna vel, aliquet sapien. Fusce purus quam, pulvinar quis enim nec, ornare luctus felis. Aliquam consectetur dapibus dictum. Morbi et ex eu risus euismod viverra sit amet sit amet augue. Nam mollis hendrerit tincidunt.
Sed posuere suscipit ipsum id sagittis. Mauris quis sapien vitae mi tristique accumsan. Praesent cursus dui vehicula leo viverra venenatis. Donec gravida lorem in quam lobortis iaculis. Mauris in feugiat turpis, ut mollis odio. Duis tincidunt massa
malesuada, suscipit orci et, laoreet odio. In ultrices vel metus eget varius. Vivamus quis libero eu lacus mattis varius. Vestibulum venenatis nisl at ligula gravida iaculis. Vestibulum metus diam, laoreet non mi et, euismod tempor dui. Integer eu
sapien ut lectus sodales cursus. In nisi nunc, faucibus feugiat velit non, molestie faucibus odio. Curabitur pretium accumsan turpis consectetur gravida. Suspendisse viverra enim a est egestas, vel lobortis augue cursus. Vivamus dignissim porta varius.
Mauris gravida id augue eget convallis. Nam id dui nec arcu dapibus congue. Sed imperdiet facilisis elementum. Nam sed magna in massa finibus viverra ac vel tortor. Morbi iaculis sollicitudin dolor vulputate luctus. Donec efficitur arcu at mauris
euismod, sit amet fermentum enim elementum. Praesent sapien sem, fringilla quis elementum a, auctor nec elit. Nunc sed justo non diam efficitur elementum. Aliquam sit amet turpis augue. Quisque ullamcorper nunc in facilisis lacinia. Mauris molestie
nibh ipsum, vitae malesuada neque blandit pharetra. Nunc viverra convallis odio pretium dictum. Sed imperdiet massa ac libero scelerisque, eget rutrum lorem accumsan. In ac lobortis nibh. Ut id risus id ante aliquet dictum lobortis eu velit. Curabitur
vitae risus bibendum, condimentum purus et, porta lectus. Nullam non nulla quis urna tincidunt auctor sed a leo.
</div>
</div>
Or simplify your code with a pseudo element and the use if vh unit to avoid all the cascading height/min-height
body {
margin: 0px;
padding: 0px;
font-family: Tahoma;
}
.outercontainer {
min-height: 100vh;
display:flex;
width: 400px;
}
.magenta {
background-color: magenta;
}
.innercontainer::before {
content:"";
background-image: url('https://i.imgur.com/vvaALIn.png'), url('https://i.imgur.com/trZrIdu.png');
background-position: left, right;
background-repeat: repeat-y;
background-color: orange;
opacity: 0.88;
z-index: 1;
position: absolute;
top: 0;
left:0;
right:0;
bottom:0;
}
.innercontainer {
position: relative;
}
.padding1 {
padding-left: 90px;
padding-right: 90px;
box-sizing: border-box;
padding-top: 32px;
}
<div class="outercontainer">
<div class="innercontainer padding1 magenta">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam convallis id tellus vitae ultrices. Phasellus elit leo, vulputate et malesuada ac, venenatis vel augue. Mauris maximus ex ac orci blandit auctor. Praesent lectus dolor, pretium vitae ultricies
vel, accumsan a ante. Fusce blandit semper suscipit. Vivamus ultricies ipsum et finibus malesuada. Aliquam tempor, tellus in bibendum fringilla, nunc lacus posuere sem, nec elementum enim eros a massa. Maecenas eleifend elementum nisi accumsan luctus.
Aenean ac tortor mollis, aliquam magna vel, aliquet sapien. Fusce purus quam, pulvinar quis enim nec, ornare luctus felis. Aliquam consectetur dapibus dictum. Morbi et ex eu risus euismod viverra sit amet sit amet augue. Nam mollis hendrerit tincidunt.
Sed posuere suscipit ipsum id sagittis. Mauris quis sapien vitae mi tristique accumsan. Praesent cursus dui vehicula leo viverra venenatis. Donec gravida lorem in quam lobortis iaculis. Mauris in feugiat turpis, ut mollis odio. Duis tincidunt massa
malesuada, suscipit orci et, laoreet odio. In ultrices vel metus eget varius. Vivamus quis libero eu lacus mattis varius. Vestibulum venenatis nisl at ligula gravida iaculis. Vestibulum metus diam, laoreet non mi et, euismod tempor dui. Integer eu
sapien ut lectus sodales cursus. In nisi nunc, faucibus feugiat velit non, molestie faucibus odio. Curabitur pretium accumsan turpis consectetur gravida. Suspendisse viverra enim a est egestas, vel lobortis augue cursus. Vivamus dignissim porta varius.
Mauris gravida id augue eget convallis. Nam id dui nec arcu dapibus congue. Sed imperdiet facilisis elementum. Nam sed magna in massa finibus viverra ac vel tortor. Morbi iaculis sollicitudin dolor vulputate luctus. Donec efficitur arcu at mauris
euismod, sit amet fermentum enim elementum. Praesent sapien sem, fringilla quis elementum a, auctor nec elit. Nunc sed justo non diam efficitur elementum. Aliquam sit amet turpis augue. Quisque ullamcorper nunc in facilisis lacinia. Mauris molestie
nibh ipsum, vitae malesuada neque blandit pharetra. Nunc viverra convallis odio pretium dictum. Sed imperdiet massa ac libero scelerisque, eget rutrum lorem accumsan. In ac lobortis nibh. Ut id risus id ante aliquet dictum lobortis eu velit. Curabitur
vitae risus bibendum, condimentum purus et, porta lectus. Nullam non nulla quis urna tincidunt auctor sed a leo.
</div>
</div>

How to force CSS grid to be specific height

I have found this question: How to set max height to a CSS grid, which talks about setting a specific height to the elements of a grid. I want to set a height to the grid itself, though, and have any elements overflowing to have a scroll bar (refer to the figure below).
Even though I set a max-height to the container element, the large text (.top) still overflows and makes the container element's height larger than its max-height. And since I don't know the size of the .bottom element (its height is auto), I can't set a max-height to the .top element.
.container {
padding: 5px;
width: 200px;
max-height: 200px;
grid-template: 1fr auto / 1fr;
grid-template-areas: "top" "bottom";
background: red;
}
.top {
background: blue;
grid-area: top;
}
.bottom {
background: green;
grid-area: bottom;
}
<div class="container">
<div class="top">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin scelerisque blandit ipsum vitae vehicula. Vestibulum id urna ac odio scelerisque venenatis. Mauris blandit vitae tortor ac auctor. Donec pharetra accumsan eleifend. Fusce porta ante at turpis venenatis, sed luctus mi efficitur. Nunc eget metus pellentesque ante lacinia facilisis. Aenean magna nisi, feugiat at ullamcorper a, tincidunt id augue. Curabitur ut nisl eu risus convallis luctus et vitae enim. Ut vitae purus sed enim tempus convallis. Vestibulum consequat scelerisque ornare.</p>
<p>Sed at urna turpis. Aenean vehicula, nunc elementum vehicula rutrum, sem orci ornare mauris, auctor ultricies quam enim quis sem. Praesent accumsan volutpat mollis. Proin tempus rhoncus lacus. Cras gravida, mauris sed suscipit vulputate, odio elit sagittis urna, non suscipit odio sapien eget ex. Ut vulputate ante sit amet diam tempus, eget tempus dolor sodales. Etiam quis orci posuere, interdum diam quis, tincidunt urna. Vivamus lectus lectus, hendrerit in sapien quis, tempor sollicitudin sem. Proin quis sem lectus. Fusce quis molestie enim, quis dapibus lacus. Nulla fringilla metus a odio lacinia feugiat. Vivamus rutrum diam placerat tristique scelerisque. Integer a iaculis justo, a tempus lorem.</p>
</div>
<div class="bottom">
<p>Little Text</p>
</div>
</div>
So how can a specific-height grid still be achieved and have any elements that are too large have a scrollbar?
You forgot to set display: grid on the container, and overflow: auto on the top:
.container {
padding: 5px;
width: 200px;
max-height: 200px;
grid-template: 1fr auto / 1fr;
grid-template-areas: "top" "bottom";
background: red;
display: grid; /* added */
}
.top {
background: blue;
grid-area: top;
overflow: auto; /* added */
}
.bottom {
background: green;
grid-area: bottom;
}
<div class="container">
<div class="top">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin scelerisque blandit ipsum vitae vehicula. Vestibulum id urna ac odio scelerisque venenatis. Mauris blandit vitae tortor ac auctor. Donec pharetra accumsan eleifend. Fusce porta ante at turpis venenatis, sed luctus mi efficitur. Nunc eget metus pellentesque ante lacinia facilisis. Aenean magna nisi, feugiat at ullamcorper a, tincidunt id augue. Curabitur ut nisl eu risus convallis luctus et vitae enim. Ut vitae purus sed enim tempus convallis. Vestibulum consequat scelerisque ornare.</p>
<p>Sed at urna turpis. Aenean vehicula, nunc elementum vehicula rutrum, sem orci ornare mauris, auctor ultricies quam enim quis sem. Praesent accumsan volutpat mollis. Proin tempus rhoncus lacus. Cras gravida, mauris sed suscipit vulputate, odio elit sagittis urna, non suscipit odio sapien eget ex. Ut vulputate ante sit amet diam tempus, eget tempus dolor sodales. Etiam quis orci posuere, interdum diam quis, tincidunt urna. Vivamus lectus lectus, hendrerit in sapien quis, tempor sollicitudin sem. Proin quis sem lectus. Fusce quis molestie enim, quis dapibus lacus. Nulla fringilla metus a odio lacinia feugiat. Vivamus rutrum diam placerat tristique scelerisque. Integer a iaculis justo, a tempus lorem.</p>
</div>
<div class="bottom">
<p>Little Text</p>
</div>
</div>

CSS for Print: Image on #top-left

I've to print a document, with a logo at #top-left and page number at #bottom-right.
My initial style for printing, is this
#page {
margin-top: 40mm;
margin-bottom: 20mm;
margin-left: 30mm;
margin-right: 30mm;
#top-left {
content: background-image: url('images/logo.png');
}
#bottom-right {
content: "Pág. " counter(page);
}
}
But neither logo, neither page number appears. It's the margin of #page, guilty?
Now we have the problem expose in this snippet. Please take a look. Can you help?
window.print();
#media print{
#page {
size: A4 portrait
margin-top: 40mm;
margin-bottom: 20mm;
margin-left: 30mm;
margin-right: 30mm;
#top-left {
content: url('http://via.placeholder.com/350x150');
width: 350px;
height: 150px;
background-color: black;
}
#bottom-right {
counter-increment: page;
content: counter(page);
}
}
body { font: 12pt Arial; }
p{ text-align: justify }
h1 { font-weight: 900;
color: #0a468c;
padding: 30px 0 20px 0;
display: block;
}
}
<html>
<head></head>
<body>
<h1>Title</h1>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non risus elementum, vestibulum nisi non, dapibus nisl. In hac habitasse platea dictumst. Nunc varius sapien id nibh ullamcorper, at luctus est vestibulum. Integer lobortis interdum quam, non iaculis urna dapibus nec. Cras et neque pretium est lobortis egestas ut non elit. Cras eget faucibus nunc. Sed accumsan augue leo, et cursus urna luctus eget. Praesent sit amet enim ultricies, vehicula sem vel, suscipit urna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam mi tellus, volutpat vel euismod sit amet, fringilla ut ante. Sed tempus metus massa, quis mollis ex dapibus et. Quisque eget aliquam nisi. Ut in elit vitae urna lobortis maximus.</p>
<p>Ut ac euismod nisi. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec bibendum enim id aliquam bibendum. Integer efficitur, ex eget consequat viverra, velit leo rhoncus massa, ut porta nisi tellus pharetra purus. Morbi id dignissim lectus, sit amet blandit augue. Cras pretium leo vel tellus auctor imperdiet. Donec id faucibus diam. Nullam posuere consectetur tristique. Nullam a rhoncus enim.</p>
<p>Praesent et bibendum metus. Sed volutpat erat sed sapien ultrices congue quis ac arcu. Proin nec porta urna. Aliquam eu mattis augue. Aliquam id velit pellentesque, varius urna pellentesque, sollicitudin tellus. Morbi ornare porttitor enim et convallis. Praesent vitae cursus leo. Cras commodo, metus quis euismod congue, lorem erat bibendum turpis, eget faucibus mi arcu sed tellus.</p>
<p>Vivamus placerat facilisis vestibulum. Nunc malesuada tempor vestibulum. Pellentesque eu pulvinar nulla, at feugiat sapien. Maecenas bibendum dolor quis ex ultrices, non ornare tortor venenatis. Phasellus ac mauris vitae lacus venenatis sagittis in ac nulla. Integer commodo nulla vitae turpis cursus, ut molestie elit sagittis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean lacinia risus id sapien placerat, ac convallis nisl vulputate. Aliquam cursus laoreet metus, et pulvinar leo. Pellentesque et nisi quis diam consequat posuere. Nullam eget erat sit amet nibh hendrerit fermentum nec eget tortor. Etiam mollis, ipsum non mollis viverra, metus libero dignissim ex, et rhoncus leo justo vitae lorem. Cras fermentum luctus accumsan.</p>
<p>Curabitur justo ligula, maximus in vehicula id, elementum ut nunc. Quisque ut malesuada ex, sit amet varius sapien. Cras nisl nibh, egestas nec ornare nec, interdum ac dui. Sed tincidunt, nibh et interdum hendrerit, odio mauris mollis metus, quis euismod nulla mi sed velit. Maecenas tincidunt velit nec venenatis finibus. Donec et sem non mauris efficitur sodales et id ante. Mauris id elementum orci. Etiam eu vulputate diam. Pellentesque semper, leo in euismod molestie, sem erat luctus magna, ut bibendum turpis odio porta dui. Mauris justo ipsum, posuere nec viverra et, commodo ac felis. Nullam scelerisque laoreet est ut dignissim. Suspendisse fermentum interdum risus, vel dapibus orci maximus quis. Etiam id quam lacinia, porttitor felis quis, pulvinar enim. Donec maximus blandit pellentesque. Suspendisse et tempus elit.</p>
</section>
</body>
</html>
this is one of the ways how you can use custom CSS for screen and for print environment.
I've built example layout and you can see how I positioned logo and counter in the top left and bottom right positions. See if that can help you. Try to open code snippent in full screen to see how it works and also I added comments in CSS section
/* CSS for screen */
#media screen {
body{
margin: 4em;
}
#logo{
background: url(http://placehold.it/100);
width: 200px; height: 200px;
}
#numbers{
position: fixed;
bottom: 4em; right: 4em;
}
}
/* CSS for printing */
#media print {
body{
margin: 2em;
}
#logo{
background: url(http://placehold.it/100);
width: 200px; height: 200px;
}
#numbers{
position: absolute;
bottom: 2em; right: 2em;
}
}
<div id="logo"> </div>
<div id="numbers">Pág. counter(page)</div>

How do you get a div to hide/scroll overflow and scale to the viewport with consistent margins?

(EDIT: my current code added to bottom of post)
I need to set a value for the height of the div in order for it to hide/scroll overflow properly, but I don't want a div at a specific pixel height. I can solve that by using % or vh units, but I don't actually want to use those units. By that, I mean I don't want my div to always be, for example, 2/3 of the page, because that means the bottom of the div will be a different distance from the bottom of the browser window, like this-
* {
padding: 0;
margin: 0;
}
html, body {
width: 100%;
height: 100%;
}
body > div {
width: 90%;
height: 90%;
background: yellow;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style2.css">
</head>
<body>
<div>
</div>
</body>
</html>
-I want it to be a consistent distance from the bottom of the browser window,
like this-
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
div {
background-color: yellow;
width: 350px;
position: fixed;
left: 10px;
top: 10px;
right: 10px;
bottom: 10px;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style2.css">
</head>
<body>
<div>
</div>
</body>
</html>
(for visual representation primarily, I am not really using the code itself as an example)
Basically, I want my div to be a variable height and hide/scroll overflow, but always 10px from the bottom.
I think these describe the same problem I'm having:
Setting a length (height or width) for one element minus the variable length of another, i.e. calc(x - y), where y is unknown
Getting a scrollable child div to Vertically fill the remainder of its parent dynamically
The answers there are to use tables or flexbox - are these the only options (without using javascript)?
My code:
* {
margin: 0;
padding: 0;
}
body {
font-family: Helvetica, Arial, sans-serif;
overflow-x: hidden;
overflow-y: hidden;
width: 100%;
height: 100%;
}
p {
font-size: 9pt;
}
a {
text-decoration: none;
color: black;
}
.container { /*this contains all the divs!!*/
padding: 10px;
}
.header {
}
.name {
float: left;
width: 25vw;
padding-right: 5vw;
}
.about {
width: 65vw;
}
.main { /*this contains divs 'left' and 'right'*/
/*background-color: #CCCCCC;*/
clear: left;
padding-top: 10px;
width: 95vw;
}
.left {
/*background-color: #E6E6E6;*/
float: left;
min-height: 10px;
width: 25vw;
padding-right: 5vw;
}
.hold { /*this is how i tried your solution*/
position: relative;
height: calc(95vh - 10px);
}
.right { /*this is my problem div*/
background-color: #FFFF00;
width: 65vw;
height: 100%;
overflow-y: hidden;
overflow-x: hidden;
}
.lorem {
margin-right: 20vw;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title> Name </title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="header">
<div class="name">
<p> Name </p>
</div> <!-- end div name -->
<div class="about">
<p> about </p>
</div> <!-- end div name -->
</div> <!-- end div header -->
<div class="main">
<div class="left">
</div> <!-- end div left -->
<div class="hold">
<div class="right">
<div class="lorem">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam feugiat facilisis purus at fermentum. Etiam ultricies iaculis nulla maximus cursus. Maecenas justo nulla, suscipit a dapibus at, lobortis nec mauris. Mauris egestas mi sit amet risus convallis, in hendrerit lorem maximus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse sollicitudin tempor libero, nec molestie dui tempor sit amet. Aenean molestie ex id nisl venenatis, quis tincidunt lectus porta. Vivamus aliquam lobortis nulla, id porta leo consequat sollicitudin. Ut iaculis neque placerat ipsum placerat tincidunt.
Quisque libero sem, hendrerit quis urna sit amet, mollis venenatis nisl. Morbi vel neque rhoncus, congue purus ac, condimentum nunc. Morbi vestibulum metus nec velit eleifend, ac sodales nulla posuere. Praesent id fermentum massa. Morbi vestibulum lorem nulla, ac vestibulum nunc auctor non. Donec ultricies placerat mauris, at pretium nibh finibus eu. Suspendisse gravida neque nisl, sit amet bibendum ante placerat eget. Sed laoreet suscipit turpis vitae ullamcorper. Mauris quis pharetra eros. Curabitur quis diam non dui elementum facilisis vel ac sem. Duis vitae augue vitae mi pulvinar placerat ut quis purus. Donec sagittis maximus aliquam. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Phasellus pharetra nisi arcu, in laoreet lacus convallis sed. Nam euismod ligula felis, ut laoreet nisl sodales eget. Maecenas cursus, augue vitae suscipit laoreet, purus magna bibendum tellus, sed maximus ex dui ac velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla eget aliquet tellus, in viverra sapien. Sed eget urna mauris. Morbi dapibus dolor et felis viverra condimentum sed a nisl. Integer congue cursus ultrices. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse nulla risus, pulvinar eget odio vitae, scelerisque cursus magna. Nam maximus eros vitae massa euismod, vel tempus felis vulputate.
Nunc blandit massa a nisl viverra, vitae molestie ex rhoncus. Pellentesque finibus luctus nisi. Sed quis luctus metus. Nullam sed augue ultrices, lacinia dolor ac, egestas ante. In non nisi nibh. Sed vitae dui libero. Duis ut ullamcorper urna. Phasellus quis fringilla leo.
Nulla porta tellus ut nibh pharetra dapibus. Mauris ullamcorper egestas aliquam. Cras posuere scelerisque imperdiet. In ultrices, leo eu molestie bibendum, augue dui semper ante, vel faucibus nibh enim sed eros. Mauris ipsum dui, placerat et tincidunt vitae, laoreet vel enim. Praesent at ligula et neque placerat blandit sed vulputate ipsum. Phasellus sodales, odio nec aliquam pretium, augue lacus mattis quam, nec vulputate purus lorem vitae nisi.
Suspendisse nisl ipsum, volutpat ac dapibus at, tincidunt eget nulla. Mauris ornare a nisi ac fringilla. Maecenas leo sapien, vulputate in dictum a, feugiat in eros. Aliquam sit amet sagittis leo. Mauris metus nisl, convallis eget mollis ut, ullamcorper eu tellus. Pellentesque eu dolor tempor, bibendum leo vitae, maximus velit. Aenean volutpat neque sit amet tellus mattis euismod.
Quisque nec vehicula orci. Curabitur varius fringilla risus, convallis tincidunt velit porttitor vitae. Aenean in lacus nec nunc tempor dignissim nec pretium sem. Nullam finibus odio quis metus ornare, in fermentum elit rutrum. Proin vitae dui in metus vehicula sodales. Donec massa neque, suscipit ac est quis, ultrices auctor risus. Cras eu auctor lectus. Nam sagittis vulputate hendrerit. Maecenas consequat odio justo, at malesuada nulla ullamcorper a. Donec arcu tellus, dignissim ut velit vel, consequat scelerisque dolor. Curabitur dictum vel risus quis consequat.
Pellentesque fringilla eu nisi sed tincidunt. Nulla feugiat sit amet purus sit amet cursus. Suspendisse nibh purus, tincidunt eu congue ut, ultricies id lectus. Phasellus convallis in nibh vel molestie. Nunc condimentum congue justo. In congue, turpis at vulputate imperdiet, dolor erat ultricies turpis, vitae egestas est augue in nisl. Ut ut leo diam. Duis vulputate ligula velit, vitae volutpat felis viverra a. Maecenas justo quam, lobortis a placerat ut, ullamcorper ac lorem. Sed eu vehicula odio.
Fusce id mauris ornare, mollis mi at, vulputate turpis. Praesent a risus feugiat, rutrum lacus nec, sodales nisi. Nulla ullamcorper libero pretium lacus accumsan, eu tempor mi porta. In tincidunt porta feugiat. Cras lectus arcu, convallis nec neque ac, vestibulum pretium ex. Curabitur mi ipsum, commodo ut eros eget, fringilla fringilla tortor. Curabitur maximus tellus ut turpis malesuada, auctor semper lectus porta. Suspendisse non sapien sagittis, dapibus tellus et, egestas quam. Aliquam vitae massa sit amet urna rhoncus rutrum sit amet et lorem. Phasellus gravida justo ut vulputate vestibulum.
Nunc sed tempus metus, sit amet volutpat mi. Quisque sed metus rutrum, iaculis enim sed, sodales lacus. Quisque quis mi ac sapien scelerisque efficitur lacinia et nunc. Proin tincidunt scelerisque turpis, non euismod ante interdum at. Sed vitae velit scelerisque, placerat nulla in, egestas justo. Mauris urna orci, pulvinar a nibh a, luctus pellentesque mauris. Nulla faucibus hendrerit urna non venenatis. Quisque nulla mi, suscipit sit amet nunc eu, dictum ullamcorper tellus. Donec lacus libero, commodo quis mauris pellentesque, feugiat iaculis nisl. Nulla facilisi. Suspendisse sed risus quis risus fringilla condimentum. Aenean aliquet in eros vel volutpat. Vivamus malesuada ultrices lorem sit amet feugiat. In interdum leo ac orci sollicitudin, maximus vestibulum nisl gravida. Sed venenatis pharetra fringilla. Etiam mauris risus, cursus et est tristique, mattis venenatis nisi.
</p>
</div> <!-- end div LOREM -->
</div> <!-- end div main -->
</div> <!-- end div hold -->
</div> <!-- end div container -->
</body>
</html>
You're on the right track! You can combine vh with calc to get the desired effect.
height: calc(100vh - 10px) - assuming the element is positioned at the top of the screen, that'll achieve the effect you're describing.
To handle scroll/overflow, you'll need an inner container - a div inside the one you set the height property on. Give that inner div { height: 100%; overflow: auto; } and you should be all set.
Here's a demo - to see it working, use the full screen view and shrink your browser's height.
/* These styles are just to make this easier to see,
and to normalize the display a little. */
* { box-sizing: border-box; margin: 0; padding: 0; }
.page { width: 100px; border: 2px solid; }
/* Here's the box that locks to some distance from the bottom, in this case 30px */
.outer {
height: calc(100vh - 30px);
position: relative;
border: 1px solid blue;
}
/* And here's the scrollable container inside it */
.inner {
height: 100%;
overflow: auto;
}
<div class="page">
<div class="outer">
<div class="inner">
content content content content
content content content content
content content content content
</div>
</div>
</div>

Sticky top div with absolute positioning

I'm using absolute positioning to have a div fill up the entire browser window. However, I wan't to combine this with a sticky div that sometimes is there and sometimes not.
To make things a little clearer, check out this jsFiddle: http://jsfiddle.net/henrikandersson/aDdRS/
I want the "top", "left" and "subheader" to stay where they are at all times.
I also want the "content" div to fill up what is left of the window.
However, sometimes I want to display the "alert" div before "content".
So far so good, as you can see in the jsFiddle. But, I want "alert" to stick to the "subheader" and stay there when scrolling. As you can see if you resize the window, "alert" will now be scrolled along with "content" - I don't want it to be.
Anyone got an idea of how to solve this?
EDIT:
I made a change in my jsFiddle, I placed the "alert" where it should be (between subheader and content-area). As you can see ( http://jsfiddle.net/henrikandersson/aDdRS/12 ) it does not push the "content-area" down since content-area has top:20px. And I can't set top:40px for example since "alert" should be able to vary in height and I want content-area to have the same css with or without the alert above.
EDIT #2:
This question deals with the same problem, but there is no solution for that question either. Seems like it's not possible without using JavaScript:
variable height scrolling div, positioned relative to variable height sibling
2018-6-18
I choose the CSS way with position: sticky.
that https://github.com/abouolia/sticky-sidebar .
doesn't work for me (I am using Vue.js 2.0 SPA with vue-router & vuex)
I also want the element position: absolute first,
and then position: sticky
Solution
parent HTML element use position: absolute to have the right position.
(don't forget to set height for parent. for example height:100%)
child HTML element position: sticky
work for me.
position: fixed
is a combination of both absolute and sticky
edit
update with some enhancements
body {
height: 100%;
overflow: hidden;
}
#top{
position: absolute;
background: yellow;
height: 50px;
width: 100%;
top: 0;
}
#left {
background: #e3e3e3;
position: absolute;
bottom: 0;
left: 0;
top: 50px;
width: 200px;
}
#right {
position: absolute;
bottom: 0;
left: 200px;
right: 0;
top: 50px;
}
#sub-header {
height: 20px;
background: orange;
}
#content-area {
position: absolute;
top: 20px;
right: 0;
bottom: 0;
left: 0;
}
#alert {
background: red;
color: white;
}
#content {
width: 100%;
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
overflow-y: auto;
position: absolute;
}
#alert + #content {
top: 20px;
}
#alert:empty + #content {
top: 0px;
}
<body>
<div class="container">
<div id="top">top</div>
<div id="left">left</div>
<div id="right">
<div id="sub-header">subheader</div>
<div id="content-area">
<div id="alert">alert!</div>
<div id="content">content<br /><br /><br />Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eget nunc magna, eget vehicula ligula. Vestibulum in massa massa, ut feugiat arcu. Suspendisse feugiat commodo tellus, id aliquam dolor cursus eu. Aliquam erat volutpat. Nulla interdum ipsum ut lectus sollicitudin blandit sodales ante malesuada. Etiam ac neque ut turpis faucibus luctus non et arcu. Maecenas ut risus ut odio fringilla sagittis. Sed nulla lorem, suscipit at condimentum quis, adipiscing eget turpis. Morbi accumsan est at tellus hendrerit sed blandit nibh sagittis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent gravida, velit id sodales bibendum, nulla leo rutrum quam, vel tempus justo mi vitae sapien. In imperdiet blandit rhoncus. Phasellus at massa nulla, ut tincidunt est. Nam viverra dui non enim semper consequat. Etiam sed libero sed ante condimentum bibendum ultrices eu nunc.
Integer massa nibh, interdum eget consectetur sed, scelerisque a ipsum. Fusce et ligula erat. Vestibulum lacus enim, facilisis id sollicitudin non, condimentum eu sem. Donec quis magna nec massa vulputate hendrerit. Nam leo nulla, fermentum eu congue quis, imperdiet sit amet orci. Aliquam ornare felis commodo est rhoncus blandit. Quisque at neque ac turpis vulputate sagittis. Donec et viverra risus. Fusce posuere lacus aliquam erat molestie sed tincidunt elit placerat. Sed pulvinar varius neque. Nullam congue adipiscing quam egestas convallis. Sed molestie massa euismod dolor facilisis laoreet.
Cras sit amet nisi sapien, non fringilla arcu. Aenean euismod gravida sem. Donec eu luctus justo. Aliquam erat volutpat. Mauris vestibulum sagittis magna, eget bibendum dolor tempor nec. Nunc rhoncus suscipit felis eu imperdiet. Sed fermentum diam non turpis tempor sit amet adipiscing leo elementum. Donec aliquam consequat elit id auctor.
Praesent vehicula, nibh a elementum imperdiet, urna nulla iaculis leo, ac hendrerit sem massa ac tortor. Suspendisse viverra consectetur libero a luctus. Maecenas iaculis mi id urna fermentum condimentum viverra tellus vulputate. Suspendisse potenti. Aliquam fermentum nulla quis dolor commodo scelerisque. Donec cursus laoreet consectetur. Praesent ultricies arcu ut ante hendrerit imperdiet. Etiam at metus lectus. Aliquam ut ligula neque. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec auctor scelerisque purus non sollicitudin. Sed elementum facilisis nisl, eget commodo est congue in. Etiam tincidunt viverra felis, vel tincidunt nulla pretium vel. Phasellus commodo bibendum magna et imperdiet. Aenean euismod condimentum magna eget venenatis. Pellentesque lorem eros, ornare at egestas vel, tincidunt non nunc. Quisque non diam nisl, ut consectetur metus. Fusce ipsum tortor, viverra et lobortis et, ullamcorper non magna. Duis elementum molestie sem, et ullamcorper neque eleifend non. Nunc iaculis quam eros, in pellentesque nunc. Donec tincidunt faucibus est, porta cursus eros imperdiet volutpat.</div>
</div>
</div>
</div>
<body>
first post
Why not scroll just the .content and not the .content-area
body {
height: 100%;
overflow: hidden;
}
#top{
position: absolute;
background: yellow;
height: 50px;
width: 100%;
top: 0;
}
#left {
background: #e3e3e3;
position: absolute;
bottom: 0;
left: 0;
top: 50px;
width: 200px;
}
#right {
position: absolute;
bottom: 0;
left: 200px;
right: 0;
top: 50px;
}
#sub-header {
height: 20px;
background: orange;
}
#content-area {
position: absolute;
top: 20px;
right: 0;
bottom: 0;
left: 0;
}
#alert {
background: red;
color: white;
}
#content {
width: 100%;
height: 100%;
overflow-y: auto;
}
<body>
<div class="container">
<div id="top">top</div>
<div id="left">left</div>
<div id="right">
<div id="sub-header">subheader</div>
<div id="content-area">
<div id="alert">alert!</div>
<div id="content">content<br /><br /><br />Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eget nunc magna, eget vehicula ligula. Vestibulum in massa massa, ut feugiat arcu. Suspendisse feugiat commodo tellus, id aliquam dolor cursus eu. Aliquam erat volutpat. Nulla interdum ipsum ut lectus sollicitudin blandit sodales ante malesuada. Etiam ac neque ut turpis faucibus luctus non et arcu. Maecenas ut risus ut odio fringilla sagittis. Sed nulla lorem, suscipit at condimentum quis, adipiscing eget turpis. Morbi accumsan est at tellus hendrerit sed blandit nibh sagittis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent gravida, velit id sodales bibendum, nulla leo rutrum quam, vel tempus justo mi vitae sapien. In imperdiet blandit rhoncus. Phasellus at massa nulla, ut tincidunt est. Nam viverra dui non enim semper consequat. Etiam sed libero sed ante condimentum bibendum ultrices eu nunc.
Integer massa nibh, interdum eget consectetur sed, scelerisque a ipsum. Fusce et ligula erat. Vestibulum lacus enim, facilisis id sollicitudin non, condimentum eu sem. Donec quis magna nec massa vulputate hendrerit. Nam leo nulla, fermentum eu congue quis, imperdiet sit amet orci. Aliquam ornare felis commodo est rhoncus blandit. Quisque at neque ac turpis vulputate sagittis. Donec et viverra risus. Fusce posuere lacus aliquam erat molestie sed tincidunt elit placerat. Sed pulvinar varius neque. Nullam congue adipiscing quam egestas convallis. Sed molestie massa euismod dolor facilisis laoreet.
Cras sit amet nisi sapien, non fringilla arcu. Aenean euismod gravida sem. Donec eu luctus justo. Aliquam erat volutpat. Mauris vestibulum sagittis magna, eget bibendum dolor tempor nec. Nunc rhoncus suscipit felis eu imperdiet. Sed fermentum diam non turpis tempor sit amet adipiscing leo elementum. Donec aliquam consequat elit id auctor.
Praesent vehicula, nibh a elementum imperdiet, urna nulla iaculis leo, ac hendrerit sem massa ac tortor. Suspendisse viverra consectetur libero a luctus. Maecenas iaculis mi id urna fermentum condimentum viverra tellus vulputate. Suspendisse potenti. Aliquam fermentum nulla quis dolor commodo scelerisque. Donec cursus laoreet consectetur. Praesent ultricies arcu ut ante hendrerit imperdiet. Etiam at metus lectus. Aliquam ut ligula neque. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec auctor scelerisque purus non sollicitudin. Sed elementum facilisis nisl, eget commodo est congue in. Etiam tincidunt viverra felis, vel tincidunt nulla pretium vel. Phasellus commodo bibendum magna et imperdiet. Aenean euismod condimentum magna eget venenatis. Pellentesque lorem eros, ornare at egestas vel, tincidunt non nunc. Quisque non diam nisl, ut consectetur metus. Fusce ipsum tortor, viverra et lobortis et, ullamcorper non magna. Duis elementum molestie sem, et ullamcorper neque eleifend non. Nunc iaculis quam eros, in pellentesque nunc. Donec tincidunt faucibus est, porta cursus eros imperdiet volutpat.</div>
</div>
</div>
</div>
<body>
Use float: left; and width: 0; and you can use transform: translateX(xxx); for set left position.
Problem solved :)
Add fixed height & width 100% to alert + position:fixed
Add padding-top to content
Only downfall is of course the extra padding if there is no alert...
See http://jsfiddle.net/aDdRS/5/
The alert scrolls with the content because it's inside the content-area which has overflow-y: auto.
Move it out of the content-area (put it in between subheader and content-area), and remove the position: absolute (and top/left/right/bottom) attributes from the content. In that example I see no reason for content to be absolute-positioned, normal flow will put it where it wants to be.
I chose to go with a JavaScript approach after all. Would have preferred a pure CSS approach but my need for IE8 support stood in the way. This answer by Myles Gray is pretty much what I did - https://stackoverflow.com/a/4933509/940517
Sticky + absolute w/o parent:
html,
body {
height: 250vh;
color: #fff;
position: relative;
}
.child {
margin: 100px auto -100px;
height: 100px;
width: 200px;
background-color: firebrick;
position: sticky;
top: 50px;
padding: 10px;
}
<div class="child">Hi, I'm sticky AND absolutely positioned!</div>

Resources