I am attempting to get elements to transition onscreen. For example purposes I have set them to transition on page load.
The elements that are not floated work perfectly fine. However, the elements that have been floated right (They have the class exleft because they should be expanding leftward) do not transition.
Can someone explain why this is happening?
JsFiddle here
HTML:
<div id="templatebox">
<div class="ribbon exright" id="r1">
</div>
<div class="ribbon exleft" id="r2">
</div>
<div class="ribbon exright" id="r3">
</div>
<div class="ribbon exleft" id="r4">
</div>
</div>
CSS:
#templatebox{
width: 100%;
height: 800px;
padding-top: 50px;
}
.ribbon{
height: 50px;
position: relative;
transition: all 1s ease;
width: 300px;
margin-bottom: 20px;
z-index: 1000;
}
.exleft{
right: -1200px;
left: 0px;
margin-right: -100px;
float: right;
}
.exright{
left: -1200px;
right: 0px;
margin-left: -100px;
}
#r1{
background-color: red;
}
#r2{
background-color: green;
}
#r3{
background-color: blue;
top: 170px;
}
#r4{
background-color: yellow;
top: 170px;
}
JS:
var ribbons = document.getElementsByClassName("ribbon");
for(var i=0, j=ribbons.length; i<j; i++){
ribbons[i].style.right = "0px";
ribbons[i].style.left = "0px";
}
The floated ribbon has both a left and right attribute value set. If both attributes are set to a pixel value, only the left value will be used.
By setting
left: auto;
You can manipulate the right value and it will work as expected.
Here is an updated JSFiddle: https://jsfiddle.net/ym5p7y6v/
Related
I want to display a border around an element, when it is hovered. Like this image:
The issue is that I don't want add to add border or outline on the element itself because I'm allowing user to change styles and it'll affect the added outline as well.
Here is what I've tried to counter this:
Created overlay div on top of the content using position: absolute
Added a div inside it to which is also set to absolute
Added onmouseover and onmouseout listener on overlay div to get the width, height, offsetLeft and offsetTop of the element
Now the issue is that because the overlay is on top, the events are not firing on elements underneath (as I want the nested element's info as well). I've also tried setting z-index but it doesn't seem to be working as well.
So, how to achieve this?
PS: The screenshot is taken from the visual builder of Webflow but I'm not sure how they are achieving this.
Here is the code:
var outlineContainer = document.querySelector('#content-container');
outlineContainer.onmouseover = outlineContainer.onmouseout = handler;
function handler(event) {
var hoverOutline = document.querySelector('.hover-outline');
if (event.type == 'mouseover') {
console.log(event.target.tagName);
var clientRects = event.target.getBoundingClientRect();
hoverOutline.style.width = `${clientRects.width}px`;
hoverOutline.style.height = `${clientRects.height}px`;
hoverOutline.style.transform = `translate(${event.target.offsetLeft}px,${event.target.offsetTop}px)`;
}
if (event.type == 'mouseout') {
hoverOutline.style.width = 0;
hoverOutline.style.height = 0;
hoverOutline.style.left = 0;
hoverOutline.style.top = 0;
}
}
#content-container {
border: 2px solid black;
background-color: white;
padding: 50px;
position: relative;
height: 100%;
}
.overlay {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
z-index: 2;
}
.hover-outline {
position: absolute;
border: 2px solid orange;
z-index: 6;
top: 0px;
left: 0px;
z-index: 3;
}
.content {
z-index: 4;
}
<div id="content-container">
<div class="overlay">
<div class="hover-outline"></div>
</div>
<div class="content">
<div class="component">
<label>Hi</label>
</div>
<div class="component">
<label>Text Field</label>
<span class="wrapper">
<input type="text" placeholder="Text Input Field" />
</span>
</div>
</div>
</div>
I may have misunderstood what is required, but could you just change the border color on hover? (And remove the JS).
#content-container {
border: 2px solid black;
background-color: white;
padding: 50px;
position: relative;
height: 100%;
}
#content-container:hover {
border: 2px solid red;
}
.overlay {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
z-index: 2;
}
.hover-outline {
position: absolute;
border: 2px solid orange;
z-index: 6;
top: 0px;
left: 0px;
z-index: 3;
}
.content {
z-index: 4;
}
<div id="content-container">
<div class="overlay">
<div class="hover-outline"></div>
</div>
<div class="content">
<div class="component">
<label>Hi</label>
</div>
<div class="component">
<label>Text Field</label>
<span class="wrapper">
<input type="text" placeholder="Text Input Field" />
</span>
</div>
</div>
</div>
This question already has answers here:
Why can't an element with a z-index value cover its child?
(5 answers)
Closed 1 year ago.
**Here is a simple code **
div {
border: 1px solid blue;
}
.one {
background-color: red;
width: 300px;
height: 300px;
}
.two {
background-color: orange;
width: 300px;
height: 300px;
position: relative;
top: 100px;
left: 100px;
z-index: 10;
}
.twenty {
background-color: pink;
width: 300px;
height: 300px;
position: relative;
top: 100px;
left: 100px;
z-index: 500;
}
.three {
margin-top: -10px;
margin-left: 10px;
background-color: yellow;
width: 300px;
height: 300px;
}
.four {
background-color: green;
width: 300px;
height: 300px;
position: relative;
top: 80px;
left: 120px;
z-index: 11;
}
<div class="one">
<div class="two">
<div class="twenty">
Can pink be above green?
</div>
</div>
</div>
<div class="three">
<div class="four">
</div>
</div>
How to make the pink square to be above the green square? Is it possible with CSS changes only without HTML changes? Why z-index applied to the .twenty class doesn't work in this case?
Thank you.
This question is NOT a duplicate of Why can't an element with a z-index value cover its child? :
In this question we'd like the child to cover, not the parent!
All layers, except the twentieth, should not have Z order. We specify absolute an order and an order of a layer on Z.
.twenty{
position: absolute;
...
z-index: 1;
}
You should set .four with a lower z-index than .two which is the element that contains .twenty but this may not be the expected result (green also becomes under the orange).
It's not possible without changing the HTML structure, like putting .twenty inside .four, or redefining all the indexes. This is how the stacking context works.
Given this code:
<div class="A">
<div class="One"></div>
<div class="Two"></div>
</div>
<div class="B">
<div class="Three"></div>
</div>
From the top view
From the side view
Lear more about the stacking context:
CSS stacking contexts and z-index made easy
The stacking context
Yes, we can ;)... if orange gets a higher z-index than green...
.two {
...
z-index: 12;
}
It's because pink is a child of orange...
I'd like my parent div to expand the height of the content, as my content will be dynamic. However, the content must be (I think) positioned absolutely so they can overlap each other vertically.
I've concluded I'll have to use JS to find the offset from the top to the bottom of the last element in the container, then set the height to that.
I'm currently doing something like this:
var lastElement = document.getElementById('three');
var bounds = lastElement.getBoundingClientRect();
var bottomOffset = bounds.top + $("#three").height();
$("#container").height(bottomOffset);
However this is clunky within my application, and the application of the height is not instantaneous, leading to a sluggy site.
Is there a better way?
var lastElement = document.getElementById('three');
var bounds = lastElement.getBoundingClientRect();
var bottomOffset = bounds.top + $("#three").height();
$("#container").height(bottomOffset);
body,
html {
height: 100% padding: 0;
margin: 0;
}
.absolute {
display: inline-block;
position: absolute;
background-color: blue;
width: 100px;
height: 100px;
}
#two {
top: 80px;
left: 120px
}
#three {
top: 160px;
left: 240px;
}
#container {
position: relative;
width: 100%;
;
background-color: yellow;
;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="absolute" id="one"></div>
<div class="absolute" id="two"></div>
<div class="absolute" id="three"></div>
</div>
View on JSFiddle
You can accomplish your result without any JS, but instead use CSS margin around the boxes to get the same result.
For the horizontal margin you can also use percentages (by request of OP).
For the vertical margins this will give unexpected results, since the percentage will still reference the width of the container (under "Property Values"), not the height.
html,body {height:100%; padding:0; margin:0;}
.container {
background-color: yellow;
}
.box {
display: inline-block;
width: 100px;
height: 100px;
margin-right: 2%;
background-color: blue;
}
.box.one {margin-top:0; margin-bottom:160px;}
.box.two {margin-top:80px; margin-bottom:80px;}
.box.three {margin-top:160px; margin-bottom:0;}
<div class="container">
<div class="box one"></div>
<div class="box two"></div>
<div class="box three"></div>
</div>
pixel-margin: https://jsfiddle.net/xzq64tsh/
percent-margin: https://jsfiddle.net/xzq64tsh/3/
Perhaps taking out the getBoundingClientRect() function, using jQuery instead might speed it up and simplify it a bit.
var lastElement = $('#three');
var bottomOffset = lastElement.offset().top + lastElement.height();
$("#container").height(bottomOffset);
body,
html {
height: 100% padding: 0;
margin: 0;
}
.absolute {
display: inline-block;
position: absolute;
background-color: blue;
width: 100px;
height: 100px;
}
#two {
top: 80px;
left: 120px
}
#three {
top: 160px;
left: 240px;
}
#container {
position: relative;
width: 100%;
;
background-color: yellow;
;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="absolute" id="one"></div>
<div class="absolute" id="two"></div>
<div class="absolute" id="three"></div>
</div>
So not sure if this one is possible but from my understanding of the spec the parent of a position fixed element should be the viewport not a parent element with position relative.
That obviously all works when it comes to positioning but not with z-index.
If you take a look at this example,
.parent {
height: 1000px;
}
.el-one {
position: relative;
z-index: 2;
height: 100px;
width: 100%;
color: red;
}
.el-two {
position: relative;
z-index: 2;
background-color: black;
height: 500px;
width: 100%;
}
.im-fixed {
position: fixed;
top: 0;
left: 0;
}
<div class="parent">
<div class="el-one">
<div class="im-fixed">Hello</div>
</div>
<div class="el-two"></div>
</div>
https://codepen.io/anon/pen/mmvXaE
The fixed element goes behind the black section if you scroll down, what I need is a way to get the red element to the front without moving it out of el-one.
I have a project where some embed code needs to become fixed when you scroll past it, this is a better example of the actual code. The example above just highlights the issue in a simple way:
<div class="parent">
<div class="el-one">
<div id="my-wrapper">
<iframe class="im-fixed"></iframe>
</div>
</div>
<div class="el-two"></div>
</div>
,
I found this online talking about what I believe has caused the issue: https://developers.google.com/web/updates/2012/09/Stacking-Changes-Coming-to-position-fixed-elements but no luck finding a workaround.
All I can think of is using JS to move the element from where an editor puts the embed code and prepending it to the body when the user scrolls past the element.
Anyone else come across this or have any ideas?
You want something like this? Increase the z-index of .el-one higher than the one you want to overlap
.parent {
height: 1000px;
}
.el-one {
position: relative;
z-index: 99;
height: 100px;
width: 100%;
color: red;
}
.el-two {
position: relative;
z-index: 2;
background-color: black;
height: 500px;
width: 100%;
}
.im-fixed {
position: fixed;
top: 0;
left: 0;
}
<div class="parent">
<div class="el-one">
<div class="im-fixed">Hello</div>
</div>
<div class="el-two"></div>
</div>
Use the following:
.el-two {
position: relative;
z-index: -1;
background-color: black;
height: 500px;
width: 100%;
}
There are several ways to solve this issue. Increasing Z-Index, cleaning up the div and etc.
I think you are sort of trying sticky header functionality. There is a new value for position CSS attribute.
position: sticky
I have cleaned up the code and removed all Z-Index. Please check the attached code snippet.
Note: Supported only in Chrome, Firefox
Not supported in IE.
.parent {
background-color: green;
position: relative;
width: 100%;
height: 5000px;
}
.header {
position: sticky;
top: 0px;
left: 0px;
height: 50px;
background-color: yellow;
}
.el-one {
background-color: blue;
color: white;
height: 100px;
width: 100%;
}
.el-two {
background-color: orange;
height: 500px;
width: 100%;
}
<div class="parent">
<div class="header">I am a header</div>
<div class="container">
<div class="el-one">
I am el-one
</div>
<div class="el-two">
I am el-two
</div>
</div>
</div>
I would like to be able to add an animation to this simple query for when the div is transitioned to its new position.
<div class="container">
<div class="left-side-bar">
<div class="long blue" id="1">
1
</div>
<div class="short red" id="2">
2
</div>
</div>
<div class='middle-side-bar'>
<div class='long green' id="3">
3
</div>
</div>
<div class='right-side-bar'>
<div class='short yellow' id="4">
4
</div>
</div>
</div>
the CSS
.left-side-bar{
clear: both;
width: 32%;
text-align: center;
float: left;
margin-top: 1%;
margin-bottom: 100px;
}
.middle-side-bar{
width: 32%;
text-align: center;
float: left;
margin: 1% 0 1% 1.6%;
}
.right-side-bar{
width: 32%;
text-align: center;
float: left;
margin: 1% 0 1% 1.6%;
}
.green {
background-color: green;
}
.long {
height: 300px;
}
.short {
height: 200px;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
Basically I want the div to be moved to its new place as an animated transition, rather than have it simply appear.
here is the jsfiddle
DEMO
Unfortunately, the replaceWith method does not work with animate in jQuery. Instead, you will probably need to find an alternative method to your solution. Here's one that slowly transitions the red box on top of the yellow box... http://jsfiddle.net/aeyg89rd/4/
I added the following jQuery, note that I used offset() to get the left and top properties of the yellow box, then I moved the red box to those left and top positions using animate() :
$(document).ready(function () {
var num4 = $("#4").offset();
$("#2").animate({ top: num4.top, left: num4.left }, 1000);
});
And I changed some CSS attributes for .red class so that I can move it around with the jQuery code above. More specifically, I changed its position to absolute, and gave it a width dimension:
.red {
position: absolute;
top: 320px;
background-color: red;
width: 150px;
}