This question already has answers here:
Why position:sticky is not working when the element is wrapped inside another one?
(1 answer)
Why bottom:0 doesn't work with position:sticky?
(2 answers)
Closed 2 years ago.
html {
height: 100%;
}
body {
height: 100%;
background-color: var(--main-bg2-color);
}
.wrapper {
position: relative;
width: 100%;
height: auto;
margin-top: 55.6px !important;
display: grid;
grid-template-columns: 17% 50% 30%;
column-gap: 15px;
}
.left-side {
background-color: var(--main-bg2-color);
color: var(--main-text-color);
height: 100%;
padding-top: 41px;
padding-left: 0;
position: sticky;
top: 55px;
}
.middle-side {
padding-top: 40px;
background-color: var(--main-bg2-color);
color: white;
height: auto;
}
.right-side {
padding-top: 40px;
padding-left: 0;
background-color: var(--main-bg2-color);
height: auto;
position: sticky;
top: 55px;
}
<nav>
</nav>
<div class="container">
<div class="wrapper">
<div class="left-side">
</div>
<div class="middle-side">
</div>
<div class="right-side">
</div>
</div>
</div>
</div>
<footer>
</footer>
I want the left side class div and right side class div to be sticky and middle content should be scrollable while scrolling down so I have used position sticky to left side class and right side class. But the position sticky is not working.
add this
// chrome
position: -webkit-sticky;
// firefox
position: -moz-sticky;
// IE
position: -ms-sticky;
Related
I have an iframe that acts as page footer. This iframe shows a pop up (the iframe has a button and it contains the pop up) but when I use it on the page the pop-up gets behind the containing div.
How can I show part of the pop up in the parent.
Updated
Now with some code :
iframe has a pop up:
https://codepen.io/oscarryz/pen/MNdjGm
<div class="page">
<div class="footer">
<button id="showpopup">Show popup</button>
<div id="infobox" class="hidden">PopUp</div>
</div>
</div>
And content uses that iframe as pop up
https://codepen.io/oscarryz/pen/rXgvNM
<div class="page">
<div class="content">Content</div>
<div class="footer">
<iframe src="https://codepen.io/oscarryz/full/MNdjGm" style='border:0;width:100%;height:500px;overflow:hidden' frameborder="0"></iframe>
</div>
</div>
This is basically the same code in this answer but using a div as pop up inside the iframe
The keyword here is stacking context.
Look at this minified example of your question, which should work as expected:
(please run the snippets in full page mode)
document.getElementById('showpopup').addEventListener('click',function() {
document.getElementById('infobox').classList.remove('hidden');
});
body {
padding: 0;
margin: 0;
text-align: center;
}
.page {
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
}
.content {
height: 80%;
width: 100%;
background: #eee;
}
.footer {
height: 20%;
width: 100%;
background: #444;
}
#showpopup {
margin: 3em;
}
#infobox {
height: 200px;
width: 80%;
position: absolute;
bottom: 15%;
left: 10%;
}
.hidden {
display: none;
}
<div class="page">
<div class="content">Page Content</div>
<div class="footer">
<button id="showpopup">Show iframe</button>
</div>
<iframe id="infobox" class="hidden" src="https://bing.com"></iframe>
</div>
Now, the difference to the page you have is either, that your page uses z-index for the main content, or absolute positioning of other elements and the iframe. If the iframe has a lower z-index or is added to the document before other absolutely positioned element, it will get hidden behind it:
document.getElementById('showpopup').addEventListener('click',function() {
document.getElementById('infobox').classList.remove('hidden');
});
body {
padding: 0;
margin: 0;
text-align: center;
}
.page {
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
}
.content {
height: 80%;
width: 100%;
background: #eee;
z-index: 99; // PROBLEM CAUSE A
position: absolute; // PROBLEM CAUSE B
}
.footer {
height: 20%;
width: 100%;
background: #444;
position: absolute;
bottom: 0;
}
#showpopup {
margin: 3em;
}
#infobox {
height: 200px;
width: 80%;
position: absolute;
bottom: 15%;
left: 10%;
}
.hidden {
display: none;
}
<div class="page">
<div class="footer">
<button id="showpopup">Show iframe</button>
</div>
<iframe id="infobox" class="hidden" src="https://bing.com"></iframe>
<div class="content">Page Content</div>
</div>
To solve this, you either need to move your iframe down in the document, or give it a higher z-index itself.
Take this snippet:
.container {
width: 150px;
height: 100px;
}
.test {
color: white;
background-color: red;
width: 100%;
height: 25%;
transition: height ease 1s;
}
.test:hover {
height: 100%;
}
<div class="container">
<div class="test">Hover Here</div>
</div>
A simple div inside a container which expands to 100% when hovered over. What I am trying to make is very simular to this, but in a navigation menu (similar to http://www.mineplex.com/).
When a user hovers over the container div (not the main box itself) I need the main div to expand from 0% to 100% in height.
I have tried using JQuery to solve this using a ".hovered" class with no luck. How can one code this?
Any help is much appreciated. Thanks!
Here's a demonstration:
Similarities between both the code snippets:
The containers make use of flex display to make a responsive navbar container, with each of its items spanning a width of 20% (which can be adjusted).
Each of the items (with relative positioning) has two sub containers (with absolute positioning), the first being overlay which we're making use for getting the blue transitioning background(z-index:1) and the second which has a fixed text on the front (z-index:2).
Now, the z-index makes sure that the overlay will be transitioned at the back and text will be fixed in the front, another thing to keep in mind is since we're transitioning it from the bottom up, we set the bottom:0 on the overlay class as well as height:0%;.
On hovering , we transition the height from 0% to 100%.
Differences between both the code snippets:
In the first snippet, we're transitioning each item on hover by making use of .items:hover .overlay.
Whereas in the second snippet, we're transitioning every item when the container is hovered instead of individual items by using .container:hover > *.items> .overlay ( ">" is a direct child selector ).
First: Hovering each item individually to expand the overlay.
.container {
width: 100%;
display: flex;
height: 80px;
background: gray;
justify-content: center;
align-items: center;
}
.items {
flex: 0 1 20%;
height: 100%;
margin-right: 5px;
position: relative;
overflow: hidden;
}
.overlay {
position: absolute;
background: blue;
z-index: 1;
width: 100%;
height: 0%;
bottom: 0;
transition: all 0.5s ease-in-out;
}
.item-text {
position: absolute;
text-align: center;
color: white;
z-index: 2;
width: 100%;
height: 100%;
top: 0;
}
.items:hover .overlay {
height: 100%;
}
<div class="container">
<div class="items">
<div class="overlay"></div>
<div class="item-text">Home</div>
</div>
<div class="items">
<div class="overlay"></div>
<div class="item-text">About</div>
</div>
<div class="items">
<div class="overlay"></div>
<div class="item-text">Contact</div>
</div>
<div class="items">
<div class="overlay"></div>
<div class="item-text">Other</div>
</div>
</div>
Second: When the user hovers over the container, expanding all the overlays.
.container {
width: 100%;
display: flex;
height: 80px;
background: gray;
justify-content: center;
align-items: center;
}
.items {
flex: 0 1 20%;
height: 100%;
margin-right: 5px;
position: relative;
overflow: hidden;
}
.overlay {
position: absolute;
background: blue;
z-index: 1;
width: 100%;
height: 0%;
bottom: 0;
transition: all 0.5s ease-in-out;
}
.item-text {
position: absolute;
text-align: center;
color: white;
z-index: 2;
width: 100%;
height: 100%;
top: 0;
}
.container:hover > *.items> .overlay {
height: 100%;
}
<div class="container">
<div class="items">
<div class="overlay"></div>
<div class="item-text">Home</div>
</div>
<div class="items">
<div class="overlay"></div>
<div class="item-text">About</div>
</div>
<div class="items">
<div class="overlay"></div>
<div class="item-text">Contact</div>
</div>
<div class="items">
<div class="overlay"></div>
<div class="item-text">Other</div>
</div>
</div>
ul{
list-style-type: none;
margin-left: 0;
padding-left: 0;
display: flex;
}
ul li{
border: 1px solid #d3d3d3;
text-align: center;
height: 100px;
width: 100px;
margin-right: 4px;
}
ul li a{
color: #000000;
text-decoration: none;
position: relative;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
ul li a:after{
content: '';
position: absolute;
background: lightblue;
left: 0;
bottom: 0;
height: 0%;
width: 100%;
z-index: -1;
}
ul li a:hover:after{
animation: bounce 1s ease-in-out forwards;
}
#keyframes bounce {
0% {height: 0%}
20% { height: 100%}
55% { height: 95%}
100% {height: 100%}
}
<ul>
<li>Lorem, ipsum.</li>
<li>Saepe, asperiores!</li>
<li>Vitae, expedita?</li>
<li>Dicta, quo.</li>
<li>Sed, et.</li>
</ul>
i wrote some code
//html
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
//This is sass
ul {
list-style:none;
background:red;
li {
display:inline-block;
padding:10px;
position:relative;
&:before {
position: absolute;
content: "";
width: 100%;
height: 0%;
left: 0;
bottom: 0;
background:blue;
transition: height ease-in-out 0.5s;
}
a {
z-index:2;
position:relative;
color:white;
}
&:hover {
&:before {
height: 100%;
}
}
}
}
Position: sticky with bottom:10px on div with class sidebar is working as expected but with property top:10px is not working as expected?
With position: sticky with bottom: 10px on div with class sidebar, when we scroll down the div stick to view port with a bottom edge above 10px to the view port.
Similarly with position: sticky with top:10px on div with class sidebar, as we scroll up the div should stick to top with the top edge of div 10px below the viewport.
But it is not working this way, what is the problem?
code: https://jsfiddle.net/c7vxwc7g/
.container{
/*width: 1654px;*/
width: 100%;
background-color: #f0f0f0;
margin: 0 auto;
}
.sidebar{
position: sticky;
bottom: 10px;
width: 400px;
margin: 5px;
background-color: teal;
height: 1000px;
display: inline-block;
}
.mainpage{
width: 1130px;
margin: 5px;
margin-left: 0px;
background-color: steelblue;
height: 6000px;
display: inline-block;
}
.footer{
height: 500px;
width: 1654;
margin: 0 auto;
margin-top: 10px;
background-color: purple
}
.test1{
background-color: red;
position: relative;
left: 0;
right: 0;
top: 0;
height: 200px;
}
.test2{
background-color: red;
position: relative;
left: 0;
right: 0;
bottom: 0;
height: 200px;
}
<body>
<div class="container">
<div class="sidebar">
<div class="test1">test1</div>
<div class="test2">test2</div>
</div>
<div class="mainpage">mainpage</div>
</div>
<div class="footer">footer</div>
</body>
In my case, the parent of the sticky element (the sidebar) had a smaller height than the content => the sticky element wasn't going down more than the sidebar's height.
The solution: I made the sidebar's height equal to the content's height (using display flex on the content's and sidebar's wrapper).
HTML:
<div clas="container">
<div class="content">This initially has a bigger height than sidebar.</div>
<div class="sidebar">
<div class="sticky"></div>
</div>
</div>
CSS:
.container { dislay: flex; } // By using this I make the sidebar the same height as the content
.sticky { position: sticky; top: 0; }
So I can't figure this out.
I'm trying to get a red vertical box to display in middle of page. I've set the div's margin to auto.
And then there's another div that holds a centered text.
Setting margin auto on both.
They are both stacking on top of eachother fine in middle of page.
However I want it to be responsive to all heights. Right now it's just responsive to the x-axis and not the height.
HTML & CSS:
.parentDiv {
position: relative;
width: 250px;
height: 450px;
margin: auto;
}
#RedBox {
width: 250px;
height: 450px;
background-color: #FF0000;
margin: auto;
}
#CSText {
position: absolute;
top: 45%;
width: 250px;
color: black;
text-align: center;
}
<div class="parentDiv" style="margin-top: auto;">
<div id="CSText" class="TextAlignCenter">
</div>
<div id="RedBox">
</div>
</div>
flexbox would be a great solution to this:
.container {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.red-box {
background-color: red;
padding: 100px;
color: white;
}
<div class="container">
<div class="red-box">text</div>
</div>
I did this for you.
https://jsfiddle.net/95ssv6q1/
HTML
<div class="parentDiv">
<div class="inner">
<div id="RedBox">
</div>
</div>
</div>
CSS
.parentDiv {
display:table;
width: 100%;
height: 100%;
position: absolute;
}
.inner{
display: table-cell;
vertical-align:middle;
}
#RedBox {
width: 250px;
height: 450px;
background-color: #FF0000;
margin: auto;
}
Here is my tricky problem. I'm trying to do this:
http://www.hostingpics.net/viewer.php?id=767312test.gif
(More clear than an explication I think).
My structure :
<header></header>
<div class="section">
<div class="text"></div>
<div class="content"></div>
<div class="img"><img src="img1.png"/></div>
</div>
<div class="section">
<div class="text"></div>
<div class="content"></div>
<div class="img"><img src="img2.png"/></div>
</div>
<div class="section">
<div class="text"></div>
<div class="content"></div>
<div class="img"><img src="img3.png"/></div>
</div>
<footer></footer>
Important informations :
"Header" is fix
"Content" fit to the screen less the height of header
Every "section" are the same but with different content
When the image comes to an end, the "content" div is unfixed.
I am using "section" for implementing a next and previous button in the header (with anchors).
My problem is the scrolling part. I am really lost when I try to fix the "content" div. I don't know how to fix everything except the scroll of the image in the active "img" div when the active "content" div hits the header. (Everyone follows? Look here : http://www.hostingpics.net/viewer.php?id=767312test.gif
For the scrolling part in the "img" div, I was thinking use a sort of "overflow:scroll" but the scrollbar is really awful.
I don't know if it's enough clear. If there is any problem I can complete my problem. I am not very comfortable with complex structures in html with JS.
Thanks for your help!
This is pretty close to what you're asking for (using CSS only).
This relies on the fact that the backgrounds are solid colors. It uses various specifically-defined height properties as well that match some padding properties.
The .top-bar and .bottom-bar elements can probably be changed to pseudo elements if you don't want the extra HTML.
HTML:
<header>Header</header>
<div class="top-bar"></div>
<div class="bottom-bar"></div>
<div class="section">
<div class="text">Section 1 Text</div>
<div class="content">
<div class="img"><img src="http://placekitten.com/100/1000"/></div>
</div>
</div>
<div class="section">
<div class="text">Section 2 Text</div>
<div class="content">
<div class="img"><img src="http://placekitten.com/200/2000"/></div>
</div>
</div>
<div class="section">
<div class="text">Section 3 Text</div>
<div class="content">
<div class="img"><img src="http://placekitten.com/300/3000"/></div>
</div>
</div>
<footer>Footer</footer>
CSS:
body {
margin: 0;
padding: 100px 0 0;
}
header {
background-color: red;
height: 100px;
position: fixed;
top: 0;
width: 100%;
z-index: 10;
}
footer {
background-color: blue;
height: 100px;
}
.section {
min-height: 400px;
}
.text {
background-color: aqua;
height: 50px;
}
.content {
background-color: green;
min-height: 100%;
padding: 40px 0;
position: relative;
}
.img {
background-color: yellow;
min-height: 70%;
margin: 0 auto;
padding: 40px 0;
text-align: center;
width: 80%;
}
.img > img {
vertical-align: middle;
}
.top-bar, .bottom-bar {
background-color: green;
height: 40px;
position: fixed;
width: 100%;
z-index: 5;
}
.top-bar {
top: 100px;
}
.bottom-bar {
bottom: 0;
}
footer, .text {
position: relative;
z-index: 6;
}
JSFiddle here.
For an almost completely correct solution, here is one with some jQuery involved.
New CSS:
body {
margin: 0;
padding: 100px 0 0;
}
header {
background-color: red;
height: 100px;
position: fixed;
top: 0;
width: 100%;
z-index: 10;
}
footer {
background-color: blue;
height: 100px;
}
.section {
min-height: 400px;
}
.text {
background-color: aqua;
height: 50px;
}
.content {
background-color: green;
min-height: 100%;
padding: 40px 0;
position: relative;
}
.img {
background-color: yellow;
min-height: 70%;
margin: 0 auto;
padding: 40px 0;
text-align: center;
width: 80%;
}
.img > img {
vertical-align: middle;
}
.top-bar, .bottom-bar {
background-color: green;
height: 40px;
position: fixed;
width: 100%;
}
.top-bar {
top: 100px;
z-index: 5;
}
.bottom-bar {
bottom: 0;
z-index: 7;
}
footer, .text {
position: relative;
z-index: 8;
}
.img-fix {
bottom: 40px;
height: 400px;
overflow: hidden;
position: absolute;
width: 100%;
z-index: 6;
}
jQuery:
$(document).ready(function(){
$(".content").each(function(){
$(this).append($(this).html());
$(this).find(".img + .img").wrap("<div class='img-fix'></div>");
});
$(window).resize(function() {
resizeImgFix();
});
resizeImgFix();
});
function resizeImgFix() {
$(".img-fix").height($(window).height() - $("header").height() - $(".top-bar").height() - $(".bottom-bar").height());
$(".img-fix").each(function(){
$(this).scrollTop($(this).prop("scrollHeight"));
});
}
JSFiddle here.
Note: It duplicates the .img element and its children. This could be memory intensive depending. However, it does make it work as intended without any visual lag or artifacts.