Given 2 elements on a web page, how can i animate one elements position so that it moves to the second element, which can be anywhere on the page.
Transform translate doesnt seem to work well as i would need to know the difference in the position of offset between the two elements.
Is there any pure css way to achieve this?
very similar to the animation on adding a product to the shopping cart on this page: https://www.triwa.com/en-gb/watches/family/current-collection/ivory-falken-steel-mesh/
You could do this sort of thing with transition. so the changing of the elements position is transitioned over 1 second or however long you want.
Example: 2 boxes, Box1 and Box2. On clicking box 2 we want it to shrink and move to box 1
HTML:
DEMO: https://jsfiddle.net/33m3t16d/1/
Hope this helps mate.
$('.box2').click(function() {
$(this).removeClass('box2');
$(this).addClass('box1');
});
.container {
position: relative;
}
.box {
background: #333;
border: 1px solid #fff
}
.box1 {
transition: all 1s;
position: absolute;
top: 0px;
left: 500px;
height: 20px;
width: 20px;
}
.box2 {
position: absolute;
top: 100px;
left: 0px;
height: 100px;
width: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="container">
<div class="box box1"></div>
<div class="box box2"></div>
</div>
Nope, there is not. You can't retrieve element positions of a random positioned element. You need to involve JS if you do not know the target position.
One approach would be, to read the target positions from the target element via JS and write a short CSS snippet into the page containing the transition rules. This way you may use JS to read and set the necessary position. But the animation itself is still rendered through the browser itself (while being defined in CSS).
I don't think there is a pure CSS way to calculate the x distance and y distance between 2 elements. You have to use JS for this. Calculate the distance between 2 elements in JS and translate the required element to the 2nd element using .css function
As others have said, theres no pure CSS way. however here is a jquery option that you can either use with the onclick="moveToElementPosition(this,'#target');" attribute
Or
$('#box2').click(function(){
moveToElementPosition('#elementToMove','#target');
});
This function will get the postion and size of the target and move your element to match. The speed it does it is dictated by the transition:all 1s;
Here's a demo: https://jsfiddle.net/33m3t16d/3/
Related
I'm trying to make a horizontal section with a parallax effect. In the background there should be an image that scrolls at a different speed than the page.
The problem is: I want the parallax element to be contained in the parent element, so the parent element works kind of like a mask for the child: the child is only visible within the boundries of the parent.
I know that this can be achieved by having the parallax element beetween two elements with backgrounds that are "above" the parallax element and obstruct it, but this method is not applicable for my case.
The obvious idea that comes to mind is to use overflow: hidden on the parent. This however breaks the 3D transforms so there is no parallax left.
How do I achieve the described effect?
Here is a codepen: https://codepen.io/rradarr/full/mdwgard.
I want the red rectangle to not be visible outside the "parallax-container" with the black border.
* {
margin: 0;
}
html, body {
height: 100%
}
main {
position: relative;
width: 100%;
perspective: 1px;
transform-style: preserve-3d;
overflow-y: auto;
overflow-x: hidden;
height: 100vh;
background-color: blue;
}
.static {
min-height: 800px;
}
.parallax-container {
border: solid black 3px;
height: 600px;
width: 100%;
transform-style: preserve-3d;
position: relative;
}
.parallax-child {
position: relative;
width: 100%;
height: 100%;
transform: translateZ(-2px) scale(2.01);
z-index: -1;
}
#img-or-whatever {
height: 900px;
width: 100%;
background-color: red;
position: relative;
z-index: -1;
}
<main>
<div class="static"></div>
<div class="parallax-container">
<div class="parallax-child">
<div id="img-or-whatever"></div>
</div>
</div>
<div class="static"></div>
</main>
As far as I know you can't achieve the described effect with translateZ.
This is because according to this article about CSS 3D
...giving overflow any value other than visible effectively forces the value of transform-style to flat, even when we have explicitly set it to preserve-3d.
The only alternative for overflow hidden is to put something "above" the parallax element as far as I know (which you said you want to avoid).
If there is really no option to put something "above" the parallax element you could try to do something similar with js (something like this for example). This is not ideal since it will imply a lot of calculations and variables and might take some time to accomplish exactly what you want (and you loose the 3D inside the container since you need overflow: hidden anyway).
If you really need the 3d inside there you could create a more complex solution with javascript that skips overflow: hidden as well. But I'd try to avoid that if is not mandatory (I'd rather add an absolute element over the overflow: hidden container where 3D is enabled. And give the absolute container transparent background if you still need 3D in that section).
Usually I would also advise to try to avoid .js for this kind of stuff (if possible) but I don't think you have a lot of options here.
You could try the :not() pseudo clss, but I don't know what you would pass into the parentheses that would be similar to not in the black square.
I have a glyphicon as such:
<div class="col-xs-4 col-sm-2">
<span class="glyphicon glyphicon-circle-arrow-up glyphicon-large"></span>
</div>
.glyphicon-large {
min-height: 260px;
font-size: 35px;
width: 1em;
display: block;
top: 50%;
margin: -0.5em auto 0px;
}
The glyphicon won't align to the center, vertically. When I open firefox, inspect element, and toggle off/on the top 50% rule, it suddenly works. How come?
Browser Bug Explanation
According to MDN on top:
For relatively positioned elements (those with position: relative), it specifies the amount the element is moved below its normal position.
Note: Percentage is applied as a percentage of the height of the element's containing block
According to W3 on top:
For relatively positioned boxes, the offset is with respect to the top edges of the box itself (i.e., the box is given a position in the normal flow, then offset from that position according to these properties).
Note: Percentages refer to height of containing block
Here's my guess:
I think what's happening is that when the browser is first rendering the visual tree, and sees top:50%;, it looks to the parent to set the height. Since no height has been specifically applied, and it has not loaded any child contents, the height of this div (and all divs) effectively starts off as zero until otherwise indicated. It then pushes down the glyph by 50% of zero.
When you toggle the property later, the browser has already rendered everything, so the calculated height of the parent container is provided by the height of its children.
Minimal, Complete, and Verifiable Example
Note: This doesn't really have anything to do with Bootstrap or Glyphicons. In order to avoid a dependency on bootstrap, we'll add top: 1px that would have been applied by the .glyphicon class. Even though it is overwritten by 50%, it still plays an important role.
Here's a simple set of parent/child elements:
<div id="container">
<div id="child">Child</div>
</div>
In order to simulate the toggling the property in a more repeatable fashion, we can just wait two seconds and then apply a style in javascript like this:
window.setTimeout(function() {
document.getElementById("child").style.top = '50%';
},2000);
Example 1 (jsFiddle)
As a starting point, let's recreate your issue.
#container {
position: relative;
/* For Visual Effects */
border: 1px solid grey;
}
#child {
position: relative;
height: 50px;
top: 1px;
/* For Visual Effects */
border: 1px solid orange;
width: 50px;
margin: 0px auto;
}
Notice that as soon as you resize the window, the browser will repaint the screen and move the element back to the top.
Example 2 (jsFiddle)
If you add top: 50% to the child element, nothing will happen when the javascript adds the property because it won't have anything to overwrite.
Example 3 (jsFiddle)
If you add top: 49% to the child element, then the DOM does have something to update so we'll get the weird glitch again.
Example 4 (jsFiddle)
If you add height: 50px; to the container instead of the child, then the top property has something to position against right from the get go and you don't need to use toggle in JavaScript.
How to Vertically Align
If you just wanted to know how to vertically center something consistently, then you can do the following:
The trick to vertically centering text is to set the line-height equal to the container height. If a line takes up 100 pixels, and the line of text online takes up 10, then browsers will try to center the text within the remaining 90 pixels, with 45 on the top and bottom.
.glyphicon-large {
min-height: 260px;
line-height: 260px;
}
Solution in jsFiddle
Tried centering a glyph icon that was inside an H1 tag, that was taking a while - so I discovered that you can actually change the font size and colour inside the SPAN tag contaning the glyph.
Thus:
<h1><span class="glyphicon glyphicon-envelope" style="font-size: 24px; color: #108db7;"></span> Mes Messages</h1>
actually worked out for me.
Have you tried ? :
<span class="glyphicon glyphicon-circle-arrow-up glyphicon-large" style="vertical-align:middle"></span>
I'm having a bit of a frustrating issue...I thought I found a few answers here but nothing as of yet seems to be working.
Here is an image to start off with:
http://www.shaunmbaer.com/wordpress/wp-content/uploads/2013/02/Melissliss_01.jpg
Then here is the html:
<section class="A">
<aside class="B"></div>
<header class="C">Title</header>
<article class="D">Lorem ipsum...</article>
</section>
And the css as of now:
A{width:100%}
B{width:220px; height:100%; float: right; background= #fff url("foo") repeat}
C{width:450px}
D{width:450px}
I am using wordpress (this bit is a post), so all of the content is automatically generated. I need div "B" to be 100% of the parent div. It does not have any content besides a repeating background image (the site is responsive and this div will disappear at the next breakpoint).
I cannot position them absolute since I cannot give the article ("D") a fixed height (at least I think that statement is correct...)
Can anyone help or point me to somewhere that can? Preferably a CSS solution, but jQuery is a-ok at this point too!
Thanks a ton2.
I'm pretty sure you can use absolute positioning for the B element, and specify 3 sides for the element to stick to:
.A {
position: relative;
}
.B {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 220px;
}
I want to align the top of a background image with the bottom of an element using CSS (so that I can make it transition in upon hover or in an animation, in case you were wondering). This element does not have a set height; I don't know what the height of the element is. Does anybody know how to do this? The solution does not have to be IE compatible; it only has to work in the latest versions of Chrome and Firefox.
EDIT: I'll award the bounty to an answer that also works for the <body> element if there is such an answer by the time that the bounty ends.
Sorry about the trouble. Gotta love CSS right? Anyhow I have two solutions for you: One just stays within the realms of using background positioning and achieves it... for the MOST part; The other one goes outside of the immediate solution, adds just a little bit extra, but is rock solid and works with any height at all. Both work with any width.
So the first one:
This works by setting the background-position to the keyword value center for the xpos and the percentage value 1000% for the ypos. Of course the % value can vary, but I just went with 1000% to be safe. In reality you could make this just big enough to push it off screen. But here's the fiddle:
http://jsfiddle.net/D5QME/
The problem with this one is that if you make the height of the parent element the exact height of the background image... it quits working. And if the height of the parent element shrinks below the height of the image, it reverse the pattern. So if you're confident that the parent element will always be taller than the BG image, this is pretty solid.
Now the second one:
This one is straight up rock solid but adds an extra element. This extra element can either be a placeholder element, like a div or whatever, or just the straight img itself. This:
1) Uses position: relative and overflow: hidden on the parent to turn it into a container
2) Uses position: relative, margin: 0 auto, and top: 100% to position the image in the center and push it just below the parent
3) and uses .parent:hover .backgroundImage to make the image transition to top: 0% when the user hovers over the parent element.
Here's the fiddle:
http://jsfiddle.net/Fwf6p/
Even though this adds an extra element, it is pretty rock solid.
Anyhow, hope this helps!
-J Cole Morrison
Another modification of J Cole's answer, but seems to work with the body tag. May also work with Hephistocles modification but haven't tested that.
CSS:
.example{
border: 1px solid red;
/* Change the height to anything you want! */
height: 400px;
/* Change the width to anything you want! */
width: 500px;
position: relative;
}
.example:hover .backgroundImage{
height: inherit;
top: 0%;
}
.backgroundImage{
background: url("http://img.gadgetian.com/Angry-Birds-Space-021-300x300.png") no-repeat top center;
position:relative;
margin: 0 auto;
top: 100%;
-webkit-transition: 1s ease all;
-moz-transition: 1s ease all;
transition: 1s ease all;
height: 0px;
}
HTML:
<body class="example">
<div class="backgroundImage"></div>
</body>
JSFiddle
To take J Cole's second answer a bit further - if you want to avoid inserting an extra element you could always use pseudo-elements. For example:
.myElm {
position: relative;
overflow: hidden;
}
.myElm:after{
content:"";
background: url("myimage.png") no-repeat top left;
top:100%;
position: absolute;
}
.myElm:hover:after {
top:0;
}
If you know the height of your element in pixels, you may be able to set its background position to be: background-position:0 npx;. Not sure otherwise. If there's a maximum height, you could always just use that. Or have a reasonable estimate/limit. The transitions may not 'ease' very uniformly, however.
There was an excellent JSFiddle in another answer just now, but it's been deleted :(
How can I do this:
an image
a simple small DIV on top of the image, centered vert/horiz, which doesn't appear until the image is rolled-over
Try this:
<div style="position:relative;top:0;left:0;">
<img src="path/2/img.png" style="z-index:1;"
onmouseover="document.getElementById('hidden').style.display='block';">
<div id="hidden" style="display:none;position:absolute;z-index:10;"></div>
</div>
If it works for you, clean it up before you deploy it! :)
NOTE: div#hidden is not yet centered over the image. If you know the width and height of it in advance, you can use this method:
#hidden {
top:50%;
left:50%;
margin-top: -(heightOfHiddenDiv/2)px
margin-left: -(widthOfHiddenDiv/2)px
}
Otherwise you will need to get the computed values of width and height in JavaScript.
If you can have a fixed width and height for the <div>, then I’d suggest this:
HTML
<div class="hover_image">
<img width="250" height="300" src="http://pauldwaite.me.uk/images/professional.jpg" />
<div class="overlay">Hello!</div>
</div>
CSS
.hover_image {
position: relative;
float: left;
}
.hover_image .overlay {
visibility: hidden;
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 3em;
margin: -2em 0 0 -55px;
padding: .5em 5px;
background: #006;
color: #fff;
}
.hover_image:hover .overlay {
visibility: visible;
}
http://jsfiddle.net/ZKXgw/
You may need to add some JavaScript to make .hover_image:hover work in earlier versions of IE, which didn’t support :hover on anything except links.
If you can’t have a fixed width/height, it’ll be a lot tricker to achieve.
Things aren't really clear to me, any way you can play with the CSS/style of the element to work around on this.
To center an element you can set the top and left by 50% where its position is set to absolute. Then set the margin-top the half size of its height in negative, and the margin-left the half size of its width in negative.
To place the div in top of the image, its z-index must be higher than the image. But first the image must have the higher z-index until its not rolled-over.
To show the div on top of the image change the z-index of the image lower then the div. Using hover or onMouseOver event. There other ways of doing this, base on your needs.
See jsfiddle in action
You can use z-index property with absolute positioning to place the div on top of the image. Since you want this to be hidden, set the "display" property in css to "none".
The second part of your question can be accomplished by using a javascript function that you can call onmouseover [ http://www.w3schools.com/jsref/event_onmouseover.asp ]. All the function would have to do is change the "display" property of the element from "none" to "block".