CSS position: sticky; bottom: 0 not sticking to bottom [duplicate] - css

This question already has answers here:
Why bottom:0 doesn't work with position:sticky?
(2 answers)
If you specify `bottom: 0` for position: sticky, why is it doing something different from the specs?
(3 answers)
Closed 11 months ago.
I can't get #up-arrow to stick to the bottom of .container.
.container {
height: 100vh;
width: 100vh;
background-color: yellow;
}
#up-arrow {
width: 45px;
height: 45px;
border: 2px solid #23ADF8;
border-radius: 23.5px;
background-color: #23ADF8;
position: -webkit-sticky;
position: sticky;
bottom: 0;
}
#up-arrow:hover {
background-color: white;
}
#up-arrow:hover img {
filter: invert(63%) sepia(35%) saturate(5648%) hue-rotate(174deg) brightness(102%) contrast(95%);
}
<div class="container">
<div id="up-arrow">
<a href="#top">
<img src="https://mandoemedia.com/wp-content/uploads/2022/03/up.svg">
</a>
</div>
</div>

The element #up-arrow will not stick to the bottom of the container with the current layout.
Because, sticky element is positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor and containing block (nearest block-level ancestor).
Here the element #up-arrow is at the top of the container, hence the element will not be able to stick to bottom on scroll.
Add some content on top of #up-arrow to see sticky working.
Sample Implementation
.container {
min-height: 100vh;
width: 100vh;
background-color: yellow;
}
#up-arrow {
width: 45px;
height: 45px;
border: 2px solid #23ADF8;
border-radius: 23.5px;
background-color: #23ADF8;
position: -webkit-sticky;
position: sticky;
bottom: 0;
}
#up-arrow:hover {
background-color: white;
}
#up-arrow:hover img {
filter: invert(63%) sepia(35%) saturate(5648%) hue-rotate(174deg) brightness(102%) contrast(95%);
}
#an-element {
height: 100vh;
}
<div class="container">
<div id="an-element"></div>
<div id="up-arrow">
<a href="#top">
<img src="https://mandoemedia.com/wp-content/uploads/2022/03/up.svg">
</a>
</div>
</div>
OR
use position: relative; parent and position: absolute; child
Working Fiddle
.container {
height: 100vh;
width: 100vh;
background-color: yellow;
position: relative;
}
#up-arrow {
width: 45px;
height: 45px;
border: 2px solid #23ADF8;
border-radius: 23.5px;
background-color: #23ADF8;
position: absolute;
bottom: 0;
}
#up-arrow:hover {
background-color: white;
}
#up-arrow:hover img {
filter: invert(63%) sepia(35%) saturate(5648%) hue-rotate(174deg) brightness(102%) contrast(95%);
}
<div class="container">
<div id="up-arrow">
<a href="#top">
<img src="https://mandoemedia.com/wp-content/uploads/2022/03/up.svg">
</a>
</div>
</div>

as you haven't wrote any other content sitcky position may not work fine.
please review below stuff and you might get what you want,
.container {
height: 300vh;
width: 100vh;
background-color: yellow;
}
#up-arrow {
position: -webkit-sticky;
position: sticky;
bottom: 0;
width: 45px;
height: 45px;
border: 2px solid #23ADF8;
border-radius: 23.5px;
background-color: #23ADF8;
}
#up-arrow:hover {
background-color: white;
}
#up-arrow:hover img {
filter: invert(63%) sepia(35%) saturate(5648%) hue-rotate(174deg) brightness(102%) contrast(95%);
}
<div class="container">
<div style="background: red;">Scroll</div>
<div style="height: 300px; background: orange;"></div>
<div class="sticky">Sticky Section</div>
<div style="background: pink;">Scroll</div>
<div style="height: 300px; background: green;"></div>
<div class="sticky">Sticky Section</div>
<div style="background: red;">Scroll</div>
<div style="height: 300px; background: orange;"></div>
<div class="sticky">Sticky Section</div>
<div id="up-arrow">
<a href="#top">
<img src="https://mandoemedia.com/wp-content/uploads/2022/03/up.svg">
</a>
</div>
<div style="background: pink;">Scroll</div>
<div style="height: 300px; background: green;"></div>
<div class="sticky">Sticky Section</div>
</div>
Note: I have made sticky at bottom position and for your understanding how bottom positioned sticky works I've also added some stuff below sticky positioned content.
Whenever content below sticky position renders position of screen will be initial(normal).
References: https://www.w3schools.com/howto/howto_css_sticky_element.asp

Related

Cannot arrange divs one below the other

I am trying to arrange my <div>s one below the other but they still end up on the same line, I tried using row and col approach but still it's not working, Answers on SO also didn't work.
Currently my code is like this
.dragAndDropBox{
position: absolute;
width: 80%;
height: 100%;
border: 1px solid #fff;
background-color: gainsboro;
border-radius: 5px;
}
.dragAndDropBox:hover{
position: absolute;
width: 80%;
height: 100%;
border: 1px solid #fff;
background-color: gray;
border-radius: 5px;
}
.dragAndDropBox .dragAndDropUpload{
position: absolute;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
outline: none;
opacity: 0;
}
.dragAndDropBox .dragAndDropProgressBar{
position: absolute;
bottom: 0;
margin: 0;
padding: 0;
width: 100%;
max-height: 10%;
outline: none;
}
.dragAndDropBox .dragAndDropText{
padding-top: 2%;
text-align: center;
line-height: 1rem;
color: #3b3b3b;
font-family: Arial
}
<div class="uploadBox w-100">
<div class="uploadDropBox">
<div class="dragAndDropBox">
<input
accept="image/*"
class="dragAndDropUpload"
type="file"
/>
<div class="dragAndDropText">Drag / Browse</div>
<div
bsstyle="success"
class="dragAndDropProgressBar mt-1 progress">
<div
role="progressbar"
class="progress-bar progress-bar-striped"
style="width: 0%;"
aria-valuenow="0"
aria-valuemin="0"
aria-valuemax="100"
/>
</div>
</div>
</div>
<div class="uploadedBox w-100">
<div>Filename Delete View</div>
</div>
</div>
I am using Bootstrap 4.3.1
The <div>s have position: absolute which puts them on top of each other.
I would suggest adding position: relative to .dragAndDropBox so all the absolutely positioned elements have a relative element to refer to.
Here's the fiddle: https://jsfiddle.net/yjdkne3b/
.dragAndDropBox {
position: relative;
width: 80%;
height: 200px;
border: 1px solid #fff;
background-color: gainsboro;
border-radius: 5px;
}
.dragAndDropBox:hover {
background-color: gray;
}
.dragAndDropBox .dragAndDropUpload {
position: absolute;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
outline: none;
opacity: 0;
}
.dragAndDropBox .dragAndDropProgressBar {
position: absolute;
bottom: 0;
margin: 0;
padding: 0;
width: 100%;
max-height: 10%;
outline: none;
}
.dragAndDropBox .dragAndDropText {
padding-top: 2%;
text-align: center;
line-height: 1rem;
color: #3b3b3b;
}
<div class="uploadBox w-100">
<div class="uploadDropBox">
<div class="dragAndDropBox">
<input accept="image/*" class="dragAndDropUpload" type="file" />
<div class="dragAndDropText">Drag / Browse</div>
<div bsstyle="success" class="dragAndDropProgressBar mt-1 progress">
<div role="progressbar" class="progress-bar progress-bar-striped" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" />
</div>
</div>
</div>
<div class="uploadedBox w-100">
<div>Filename Delete View</div>
</div>
</div>
I hope this is the solution you are looking for.
Also, you don't have to repeat the properties from the element on hover. If only the background changes on hover it's ok to change just that and the other properties will remain the same. :)
Use <br> as a line break (end-of-line).
I think it is because of the "position: absolute" in your CSS. This makes block elements only use as much space as they need.
You can read more about this here: Does adding a position: absolute to a block element make it behave like an inline?

Border-box not working

I am trying to have my chipped edge match the box size. I tried box-sizing in a number of situations but could not make it work.
.box {
background-color: #009fbd;
width: 100%;
}
.box p {
color: #fff;
}
.chipped-corner:before {
content: '';
position: absolute;
bottom: 5px;
left: 15px;
display: block;
height: 0;
width: 100%;
border-top: 7px solid #009fbd;
border-right: 7px solid transparent;
box-sizing: border-box;
}
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div class="col-xs-4 col-sm-3">
<div class="text-center chipped-corner">
<div class="box">
<div>
<p>Pulp Fiction</p>
<p>Best Movie Ever.</p>
</div>
</div>
</div>
</div>
something like this:
set relative style to same elem
.box {
background-color: #009fbd;
width: 100%;
}
.box p {
color: #fff;
}
.chipped-corner{
position: relative;
}
.chipped-corner:before {
content: '';
position: absolute;
left: 0;
bottom: -7px;
display: block;
height: 0;
width: 100%;
border-top: 7px solid red;
border-right: 7px solid transparent;
}
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div class="col-xs-4 col-sm-3">
<div class="text-center chipped-corner">
<div class="box">
<div>
<p>Pulp Fiction</p>
<p>Best Movie Ever.</p>
</div>
</div>
</div>
</div>
The issue is not with border-box. The issue is with the bootstrap column class you added.
It comes with 15px of padding on both sides you need to remove.
You need to reset the left position of the :before element to 0.
That should get you close to what you're looking for.

How to set absolute div over overflow hidden grandparent

I got an overflow hidden container (scrollable) and within a couple of tiles with custom dropdowns for better touch usability.
The problem: I can't get the dropdown list shown above the overflow hidden grandparent:
<div id="overflow">
<div class="tile">
<div class="absolute"></div>
</div>
<div class="tile">
<div class="absolute"></div>
</div>
<div class="tile">
<div class="absolute"></div>
</div>
</div>
#overflow{
height: 190px;
width: 200px;
border: 1px solid black;
overflow: hidden;
}
.tile {
clear: both;
margin: 10px 0 0 10px;
width: 180px;
height: 50px;
position: relative;
border: 1px solid green;
z-index: auto;
}
.absolute {
position: absolute;
left: 20px;
bottom: -20px;
width: 50px;
height: 30px;
border: 1px solid red;
background: red;
z-index: 99;
}
https://jsfiddle.net/enmwmtw8/
Any ideas how to achieve this?
This can't be achieved in this way. As whatever is in the overflow: hidden container can't be shown outside of it.
The only way to do this would be to place the dropdown outside the container

Vertically center text and image inside floating div

I've seen an article about vertical centering of text and image. I've seen an article about vertical centering text inside a floated div.
But not both conditions.
Here's my experiment:
.phase {
width: 500px;
height: 500px;
border: 1px solid red;
}
.float-right {
float: right;
}
.carousel {
height: 300px;
display: table-cell;
vertical-align: middle;
border: 1px solid orange;
}
.circle {
float: left;
height: 50px;
width: 50px;
vertical-align: middle;
border: 1px solid green;
border-radius: 50%;
background-color: white;
}
.thumbnail {
float: left;
}
<div class="phase">
<div class="float-right">
<div class="carousel">
<div class="circle">
</div>
<div class="thumbnail">
<img src="https://www.google.com/images/nav_logo231.png" style="width:160px;height:160px;vertical-align:middle" />
</div>
</div>
</div>
<h1>I love css</h1>
</div>
Notice the image is vertically centered, but the green circle is not vertically centered.
How can I get both the image and the green circle vertically centered?
You can achieve a totally centered element using calc and view-units:
#example {
width: 100px;
height: 100px;
border: 1px solid green;
border-radius: 50px;
position: fixed;
top: calc(50vh - 50px);
left: calc(50vw - 50px);
}
<div id="example"></div>
This example will keep it right in the centre even with scrolling, etc - but you could place it centre based on the initial view using an absolute position.
My fixed code. It works in IE and in Chrome.
top: calc(0.5vh + 50px); is what does the trick. 50px of course would be the height of the element you want to vertically center.
.phase {
width: 500px;
height: 500px;
border: 1px solid red;
}
.float-right {
float: right;
}
.carousel {
height: 300px;
display: table-cell;
vertical-align: middle;
border: 1px solid orange;
}
.circle {
position: relative;
float: left;
top: calc(0.5vh + 50px);
height: 50px;
width: 50px;
vertical-align: middle;
border: 1px solid green;
border-radius: 50%;
background-color: white;
}
.thumbnail {
float: left;
border: 1px solid black;
}
<div class="phase">
<div class="float-right">
<div class="carousel">
<div class="circle">
</div>
<div class="thumbnail">
<img src="https://www.google.com/images/nav_logo231.png" style="width:160px;height:160px;" />
</div>
</div>
</div>
<h1>I love css</h1>
</div>
You need to place the circle in a container and set the container's line-height property. Try this:
.phase {
width: 500px;
border: 1px solid red;
}
.float-right {
float: right;
}
.carousel {
height: 300px;
display: table-cell;
vertical-align: middle;
border: 1px solid orange;
}
.container {
float: left;
height: 300px;
line-height: 300px;
}
.circle {
display: inline-block;
height: 50px;
width: 50px;
border: 1px solid green;
border-radius: 50%;
background-color: white;
}
.thumbnail {
display: inline-block;
}
<div class="phase">
<div class="float-right">
<div class="carousel">
<div class="container"><div class="circle">
</div></div>
<div class="container"><div class="thumbnail">
<img src="https://www.google.com/images/nav_logo231.png" style="width:160px;height:160px;vertical-align:middle" />
</div></div>
</div>
</div>
</div>

Trying to get a div positioned over two others either relatively or absolute

HTML:
<div id="outer1">
<div class="bg">
<div class="top"></div>
<div class="base"></div>
</div>
<div class="content"></div>
</div>
<div id="outer2">
<div id="bg">
<div class="top"></div>
<div class="base"></div>
</div>
<div class="content"></div>
</div>
CSS2:
div { width: 100%; }
#outer1, #outer2 {position: relative;}
#outer1 .top { height: 200px; background-color: blue; }
#outer1 .base { height: 200px; background-color: yellow; }
#outer2 .top { height: 200px; background-color: green; }
#outer2 .base { height: 200px; background-color: yellow; }
.content {
width: 160px; margin: 0 auto;
position: relative; bottom: 250px; height: 300px; background-color: white; border: 1px solid black;}
This is the fiddle
The white, black-bordered div (.content) is supposed to sit on the split-coloured background (.bg) (as it is).
Using relative positioning - but the space i've told it to move up by (250px), is still been taken by it's parent (#outer1). (there's a gap between to the two 'outer' divs - they should be touching)
I tried absolute positioning but because the content div is taller than the relative content, the height is not honoured. And becuase it's dynamic content I cannot give it a fixed height (although i did for illustration)
One option is javascript, another is using a background-repeater for the top half.
Can it be achieved with pure CSS2?
Edit: Complete rewrite...
Here is the new fiddle: http://jsfiddle.net/FSXj8/14/
Okay so I took the liberty to start from scratch. Here is the html
<div id="outer1" class="container">
<div class="content">
<div class="innerContent">hello world</div>
</div>
<div class="top"></div>
<div class="base"></div>
</div>
<div id="outer2" class="container">
<div class="content">
<div class="innerContent">hello world</div>
</div>
<div class="top"></div>
<div class="base"></div>
</div>
And here is the CSS
div {
width: 100%;
}
.container {
height: 400px;
display: table;
position: relative;
}
.top, .base {
position: absolute;
left: 0;
height: 50%;
z-index: 0;
}
.top {
top: 0;
}
.base {
bottom: 0;
}
#outer1 .top {
background-color: blue;
}
#outer1 .base {
background-color: yellow;
}
#outer2 .top {
height: 50%;
background-color: green;
}
#outer2 .base {
height: 50%;
background-color: yellow;
}
.innerContent {
min-height: 100px;
border: 1px solid black;
background-color: white;
width: 100px;
}
.content {
display: table-cell;
position: relative;
vertical-align: middle;
z-index: 1;
background-color: transparent;
height: 100%;
}
Not sure if this is what you want, you said something about not using absolute:
.content {
width: 100px; margin 0 auto;
position: absolute; margin-top:-250px; height: 100px; background-color: white; border: 1px solid black;}
http://jsfiddle.net/FSXj8/7/

Resources