I have an HTML page where I need to make a deeply nested element appear above a neighboring ancestor.
Here is an example JSFiddle: https://jsfiddle.net/nLa607g5/1/
This HTML structure can’t be changed. Using CSS (preferably) or JavaScript, is there any way I can make the red button appear on top of the overlay, but the blue portion appear behind the overlay?
The following are the two main classes that deal with the overlay and button:
.overlay {
background-color: rgba(0, 0, 0, 0.3);
backdrop-filter: blur(2px);
border-radius: 5px;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
#cntrl {
float: left;
}
.modal {
overflow: auto;
display: block;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
}
.dialog {
background: blue;
width: 100px;
height: 100px;
display: block;
}
.btn {
margin-top: 20px;
position: relative;
background: red;
}
<div class="overlay"></div>
<div id="app">
<div id="cntrl">
<div>
<div>
<div class="modal">
<div class="dialog">
<span>should appear behind overlay</span>
<div class="content">
<div class="footer">
<button class="btn">
Should appear on top of overlay
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Impossible with CSS and no HTML. JavaScript is the only option. Basically, you append the overlay to the footer and the button to the overlay -- exactly what you'd do with HTML.
const overlay = document.querySelector('.overlay');
const footer = document.querySelector('.footer');
const button = document.querySelector('.btn');
footer.append(overlay);
overlay.append(button);
.overlay {
background-color: rgba(0, 0, 0, 0.3);
backdrop-filter: blur(2px);
border-radius: 5px;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
#cntrl {
float: left;
}
.modal {
overflow: auto;
display: block;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
}
.dialog {
background: blue;
width: 100px;
height: 100px;
display: block;
}
.btn {
margin-top: 20px;
position: relative;
background: red;
}
<div class="overlay"></div>
<div id="app">
<div id="cntrl">
<div>
<div>
<div class="modal">
<div class="dialog">
<span>should appear behind overlay</span>
<div class="content">
<div class="footer">
<button class="btn">
Should appear on top of overlay
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I'm trying to create a design using multiple divs using CSS.
I'm already written code for it but don't know what is the problem with my code as my left and right side div not aligning at vertically center and all the divs are not overlapped with main yellow centered div which is I'm unable to achieve.
Note: I tried this with z-index but did not get what I want.
Output I'm getting:
Output I want to achieve:
My code :
<!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></title>
</head>
<style>
.maind {
margin: 0px auto;
width: 90%;
padding: 10px;
height: 900px;
background-color: rgb(9, 252, 9);
position: relative;
}
.fdiv {
margin: auto;
width: 25%;
padding: 10px;
height: 100px;
background-color: rgb(10, 233, 222);
margin-top: 30px;
border: 2px solid red;
}
.sdiv {
width: 55%;
height: 600px;
background-color: #ffff00ec;
}
.tdiv {
margin: auto;
width: 25%;
padding: 10px;
height: 100px;
background-color: rgb(10, 233, 222);
border: 2px solid red;
}
p {
text-align: center;
}
.wrap {
display: flex;
flex-direction: row;
}
.wr1 {
width: 25%;
height: 100px;
background-color: rgb(10, 233, 222);
border: 2px solid red;
}
</style>
<body>
<div class="maind">
<div class="fdiv">
<p>Some content here...</p>
</div>
<div class="wrap">
<div class="wr1">
<p>Some content here..</p>
</div>
<div class="sdiv">
<p>Some content here..</p>
</div>
<div class="wr1">
Some content here...
</div>
</div>
<div class="tdiv">
<p>Some content here..</p>
</div>
</div>
</body>
</html>
Please somebody help me with the Source Code I tried almost all the related answer.
You can use Flexbox or Positioning.
Using Positioning makes it more flexible to add content to the holder element.
While Flexbox is more flexible when it's about adding and aligning boxes.
# Positioning
Description:
Create 4 elements to be the boxes.
Each .box has it's direction.
Example: <div class="box top"></div>.
Wrap all of them in div.boxes. This way you can separate the .boxes from the content (if there) in the holder,
<div class="boxes">
<div class="box top"></div>
<div class="box right"></div>
<div class="box left"></div>
<div class="box bottom"></div>
</div>
Style the the position of .wrapper so all the positioned absolute elements stays in the .wrapper.
.wrapper {position: relative;}
Finally, set the position of each box:
Example:
.box.top {
top: 0;
left: 50%;
transform: translateX(-50%);
margin-top: -40px;
}
Notes:
Don't use:
left property on .box.right.
top property on .box.bottom.
It won't set the negative margin which pushes them to edges.
In case content added to the holder (.wrapper), wrap the content in div.content and add inner space using padding. The value of padding in the code example is 40px, which it's related to the .boxes dimenstions.
The space (padding) is added to prevent overflow between content and .boxeses. And we can go further with styling the .boxes with overflow and z-index property.
For more about using negative maring and the boxes dimenstions:
Check for Notes in Flexbox
The Code:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrapper {
position: relative;
width: 600px;
height: 600px;
border: 1px solid;
margin: 50px auto;
}
.box {
position: absolute;
border: 1px solid;
background-color: red;
}
.box.top, .box.bottom {
width: 200px;
height: 80px;
}
.box.left, .box.right {
width: 80px;
height: 200px;
}
.box.top {
top: 0;
left: 50%;
transform: translateX(-50%);
margin-top: -40px;
}
.box.bottom {
bottom: 0;
left: 50%;
transform: translateX(-50%);
margin-bottom: -40px;
}
.box.left {
top: 50%;
left: 0;
transform: translateY(-50%);
margin-left: -40px;
}
.box.right {
right: 0;
top: 50%;
transform: translateY(-50%);
margin-right: -40px;
}
.content {
padding: 40px; /* check notes */
}
<div class="wrapper">
<div class="boxes">
<div class="box top"></div>
<div class="box right"></div>
<div class="box left"></div>
<div class="box bottom"></div>
</div>
<div class="content">
<h1>Hello World!</h1>
</div>
</div>
# Flexbox
Description:
Create 3 elements to hold the .boxes.
top: holding top box
center: holding left and right boxes
bottom: holding bottom box
In other words:
Each .box is nested (a child) in a div that has the class of the direction.
Example: <div class="top">BOX</div>.
Left and right are nested in center.
HTML:
<!-- top box -->
<div class="top">
<div class="box"></div>
</div>
<!-- left, right boxes -->
<div class="center">
<div class="left">
<div class="box"></div>
</div>
<div class="right">
<div class="box"></div>
</div>
</div>
<!-- bottom box -->
<div class="bottom">
<div class="box"></div>
</div>
Wrap all of them in a div.wrapper:
<div class="wrapper">
<!-- top box -->
<div class="top"></div>
<!-- left, right boxes -->
<div class="center"></div>
<!-- bottom box -->
<div class="bottom"></div>
</div>
The lines below will style the 3 elements and set them to their positions, .top will be centered (left right) and on top, .center will be centered from all the directions, .bottom is centered (left right) and at the bottom, by displaying the .wrapper children horizontally (flex-direction: column;) and centered (align-items: center;) with (space-between) them, using flex.
Check: A Complete Guide to Flexbox
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
Then we do something similar with the .center element, by displaying both of left and right next to each other, centered and space-between them.
(No flex-direction property in the declaration, since the default is in a row (vertically))
.wrapper .center {
width: 100%; /* Don't delete, check notes */
display: flex;
justify-content: space-between;
align-items: center;
}
And finally, with negative margin we move the boxes to the edges.
.top .box {
margin-top: -40px;
}
.bottom .box {
margin-bottom: -40px;
}
.center .left .box {
margin-left: -40px;
}
.center .right .box {
margin-right: -40px;
}
Notes:
The left and right boxes are (width: 80px), each, which means the margin should be -40px (80 / 2 = 40) to set on center.
left: margin-left: -40px
right: margin-right: -40px
Same for top and bottom, since the dimensions are flipped.
top: margin-top: -40px
bottom: margin-bottom: -40px
This way, all the boxes are gonna be centered at the edges.
By default, when displaying with flexbox, the parent(.center) will take the width of it's content/children (fitted)! which means, width: 40px * 2, since we have 2 boxes in there. Now to make sure that the space-between value works, we should "stretch" the .center element (parent) by styling it's width to 100% which allows to the boxes to have as much as space-between, then every box is gonna be on it's position.
.wrapper .center {
width: 100%; /* Don't delete, check notes */
}
The Code:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrapper {
border: 1px solid;
max-width: 600px;
min-height: 600px;
margin: 60px auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.box {
border: 1px solid;
background-color: red;
}
.wrapper .top .box,
.wrapper .bottom .box {
width: 200px;
height: 80px;
}
.wrapper .center .box {
width: 80px;
height: 200px;
}
.top .box {
margin-top: -40px;
}
.bottom .box {
margin-bottom:-40px;
}
.wrapper .center {
width: 100%; /* Don't delete, check notes */
display: flex;
justify-content: space-between;
align-items: center;
}
.center .left .box {
margin-left: -40px;
}
.center .right .box {
margin-right: -40px;
}
<div class="wrapper">
<div class="top">
<div class="box"></div>
</div>
<div class="center">
<div class="left">
<div class="box"></div>
</div>
<div class="right">
<div class="box"></div>
</div>
</div>
<div class="bottom">
<div class="box"></div>
</div>
</div>
EDIT:
As #anatolhiman mentioned in the comments:
but negative margins will create a problem by having the elements
overflowing right and left (especially on narrow screens).
A simple solution:
(same works for both examples)
wrap the HTML that we added before in another div, .container for example, and add spacing with CSS, either padding or margin works, depends on your situation.
So the question is...
Is it a space within the .container? --> padding.
Or outside of it? --> margin.
Give the .container a background-color, resize the window, and check both margin and padding to see the differences.
HTML - Update:
<div class="container">
<div class="wrapper">
</div>
</div>
CSS - Add:
/* outside space */
.container {margin: 50px;}
/* Or */
/* inside space */
.container {padding: 50px;}
You may have to edit the margin property in .wrapper for top bottom.
Extra space added (50px) to include spaces for the .boxes as well.
Remember: .wrapper{max-width: VALUE} is taking a place in this functionality, since it's max-width is X but it could be smaller. So if the property is width: and not max-width then it'll behave differently, and won't work as expected (fully responsive), unless we use #media query or JavaScript.
Maybe something like following snippet, with absolute positioning:
.maind {
margin: 0px auto;
width: 90%;
padding: 10px;
height: 900px;
background-color: rgb(9, 252, 9);
position: relative;
}
.fdiv {
margin: auto;
width: 25%;
padding: 10px;
height: 100px;
background-color: rgb(10, 233, 222);
margin-top: 30px;
border: 2px solid red;
position: absolute;
top: 0;
left: 35%;
z-index: 22;
}
.sdiv {
width: 80%;
position: absolute;
top: 10%;
left: 10%;
height: 600px;
background-color: #ffff00ec;
z-index: 12;
margin: 0 auto;
}
.tdiv {
margin: auto;
width: 25%;
padding: 10px;
height: 100px;
background-color: rgb(10, 233, 222);
border: 2px solid red;
position: absolute;
bottom: 20%;
left: 35%;
z-index: 22;
}
p {
text-align: center;
}
.wrap {
display: flex;
flex-direction: row;
}
.wr1 {
width: 25%;
height: 100px;
background-color: rgb(10, 233, 222);
border: 2px solid red;
position: absolute;
top: 35%;
left: 0;
z-index: 22;
}
.wr2 {
width: 25%;
height: 100px;
background-color: rgb(10, 233, 222);
border: 2px solid red;
position: absolute;
top: 35%;
right: 0;
z-index: 22;
}
<div class="maind">
<div class="fdiv">
<p>Top...</p>
</div>
<div class="wrap">
<div class="wr1">
<p>Left..</p>
</div>
<div class="sdiv">
<p>Somessss content here..</p>
</div>
<div class="wr2">
<p>Right...</p>
</div>
</div>
<div class="tdiv">
<p>Bottom..</p>
</div>
</div>
I have several divs with absolute position on top of primary div which has relative position (duh). I am trying to make one div change its background-color etc when hovering another div within same parent div.
Now, I'm aware of adjacent-div classes but they don't seem to work (maybe because of absolute positioning).
Below is an example of my code (actual is a lot bigger). What would be best way to change for e.g. m2wrap-back width & color when hovering on m2wrap-hover (which overlays 100% on other divs)?
P.S. If CSS alone ain't an option, a jQuery solution can also work.
<div class="m2wrap">
<div class="m2wrap-back">
<h3 class="m2wrap-back-title">Title</h3>
</div>
<h3 class="xhfb-text"> Some text here.. </h3>
<div class="m2wrap-bz1"></div>
<div class="m2wrap-bz2"></div>
<div class="m2wrap-hover"></div>
</div>
<style>
.m2wrap {
position: relative
}
.m2wrap-back {
position: absolute;
top: 15px;
left: 0;
width: 110px;
height: 0;
text-align: center;
vertical-align: middle;
}
.m2wrap-hover {
position: absolute;
width: 100%;
height: 100%;
z-index: 2;
border-radius: 4px;
opacity: 0.6;
cursor: pointer;
}
div.m2wrap-hover:hover {
background-color: #bf0000;
}
</style>
You can not do it with pure css and your current html structure, need javascipt or jquery to do this.
Example:
$('.m2wrap-hover').hover(function() {
$(this).closest('.m2wrap').find('.m2wrap-back').addClass('hover');
}, function() {
$(this).closest('.m2wrap').find('.m2wrap-back').removeClass('hover');
})
.m2wrap {
position: relative
}
.m2wrap-back {
position: absolute;
top: 15px;
left: 0;
width: 110px;
height: 0;
text-align: center;
vertical-align: middle;
}
.m2wrap-hover {
position: absolute;
width: 100%;
height: 100%;
z-index: 2;
border-radius: 4px;
opacity: 0.6;
cursor: pointer;
}
div.m2wrap-hover:hover {
background-color: #bf0000;
}
.m2wrap-back.hover {
width: 120px;
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="m2wrap">
<div class="m2wrap-back">
<h3 class="m2wrap-back-title">Title</h3>
</div>
<h3 class="xhfb-text"> Some text here.. </h3>
<div class="m2wrap-bz1"></div>
<div class="m2wrap-bz2"></div>
<div class="m2wrap-hover">hover here</div>
</div>
Or if you want to use just css, you need to change the order of your elements (because it has position: absolute so the order doesn't matter):
.m2wrap {
position: relative
}
.m2wrap-back {
position: absolute;
top: 15px;
left: 0;
width: 110px;
height: 0;
text-align: center;
vertical-align: middle;
}
.m2wrap-hover {
position: absolute;
width: 100%;
height: 100%;
z-index: 2;
border-radius: 4px;
opacity: 0.6;
cursor: pointer;
}
div.m2wrap-hover:hover {
background-color: #bf0000;
}
.m2wrap-hover:hover + .m2wrap-back {
width: 120px;
color: red;
}
<div class="m2wrap">
<h3 class="xhfb-text"> Some text here.. </h3>
<div class="m2wrap-bz1"></div>
<div class="m2wrap-bz2"></div>
<div class="m2wrap-hover">hover here</div>
<div class="m2wrap-back">
<h3 class="m2wrap-back-title">Title</h3>
</div>
</div>
I'm trying to get the text in the fixed div to change as you scroll past the main divs that contain the images. I tried following the solution in Changing div content based on scroll position but it won't work. Here is my attempt using that method: http://jsfiddle.net/st6q1Lmo/5/.
I'm a beginner so it's hard for me to write code from scratch. I must be doing something wrong... I would appreciate any help. Thank you!
This is my HTML and CSS without any JS (http://jsfiddle.net/7tdnw1eb/6/):
UPDATE: Thanks to the lead #tera_789 gave me, I've almost got it to work. For the first and third div it works, but for the second the content won't update in the fixed div. I know it could be because the video is only 90vh and the video itself won't scroll in the container... However I need it to be 90vh. How can I get around this? jsfiddle.net/7tdnw1eb/12
body {
background-color: #797979;
color: black;
font-family: serif;
font-size: 2vw;
line-height: 1.1em;
}
#about {
padding-bottom: 1em;
}
#wrapper {
max-width: 100vw;
max-height: 100vh;
overflow: scroll;
padding-top: 1em;
padding-bottom: 1em;
}
.project {
background-color: transparent;
width: 100vw;
height: 100vh;
position: sticky;
top: 0;
padding: 0 2em;
overflow: scroll;
}
.content__container {
width: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#count {
color: black;
width: 20%;
display: block;
position: fixed;
top: 0;
right: 0;
padding: 1em 2em 2em 0;
z-index: 99999999999;
}
img {
max-width: 100%;
}
<div id="wrapper">
<div id="count">
<p>1/3</p>
</div>
<div id="about">
Wassup everyone
</div>
<div class="project">
<div class="content__container">
<img src="https://www.what-dog.net/Images/faces2/scroll001.jpg">
</div>
</div>
<div class="project">
<div class="content__container">
<img src="https://static.boredpanda.com/blog/wp-content/uploads/2017/09/funny-dog-thoughts-tweets-1.jpg">
</div>
</div>
<div class="project">
<div class="content__container">
<img src="https://ksrpetcare.com/wp-content/uploads/2017/04/41059-Cute-Yellow-Labrador-puppy-in-play-bow-white-background.jpg">
</div>
</div>
</div>
Take a look at this: onscroll event
I have built a div container with HTML and jQuery, where when you hover over it another panel slides over the top. But I am experiencing the sliding panel "yoyo" about. I think this is because when the panel slides over the div the hover state is triggered then lost and so the panel pops up and down again continuously.
What I want to happen is while you are hovering over anywhere in the square the panel shows and when you are not in the square it doesn't.
Here is a fiddle so you can see what the problem is, maybe it is easier explained this way.
https://jsfiddle.net/xa5gtd2u/3/
Also here is the code
HTML
<div class="container">
<div class="services-blocks">
<img class="alignnone size-full wp-image-1974" src="http://placehold.it/250x250" alt="Design" width="250" height="250" />
<h3>title here</h3>
</div>
<div class="services-slide-panel">
<h3>title here</h3>
Some text here
Some text here
Some text here
Some text here
</div>
</div>
CSS
.services-slide-panel {
background: #f3535e;
width: 100%;
position: absolute;
left: 0;
bottom: 0;
top: 0;
display: none;
color: #ffffff;
}
.services-slide-panel h3 {
color: #ffffff;
}
.services-blocks h3 {
text-align: center;
position: absolute;
bottom: 5%;
width: 100%;
color: #ffffff;
}
.container {
width: 250px;
height: 250px;
position: relative;
}
jQuery
$(document).ready(function() {
$(".services-blocks").hover(function() {
$(this).next(".services-slide-panel").slideToggle("slow");
});
});
CSS3 transition is always a better pick to do these kind of effects. Moreover you have to hover() on .container otherwise the slided in div will take the hover instead and the will invoke hoverout part of the hover() function.
$(document).ready(function() {
$(".container").hover(function() {
$(this).find(".services-slide-panel").addClass("slow");
}, function() {
$(this).find(".services-slide-panel").removeClass("slow");
});
});
.services-slide-panel {
background: #f3535e;
width: 100%;
position: absolute;
left: 0;
bottom: 0;
top: 110%;
color: #ffffff;
transition: all 0.3s ease;
}
.services-slide-panel.slow {
top: 0%;
}
.services-slide-panel h3 {
color: #ffffff;
}
.services-blocks h3 {
text-align: center;
position: absolute;
bottom: 5%;
width: 100%;
color: #ffffff;
}
.container {
width: 250px;
height: 250px;
position: relative;
overflow:hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="services-blocks">
<img class="alignnone size-full wp-image-1974" src="http://placehold.it/250x250" alt="Design" width="250" height="250" />
<h3>title here</h3>
</div>
<div class="services-slide-panel">
<h3>title here</h3> Some text here Some text here Some text here Some text here
</div>
</div>
Fiddle here