This question already has an answer here:
CSS animation on hover stay at last keyframe when using transform: rotate
(1 answer)
Closed 8 years ago.
I have a CSS3 Transition but right at the end of the transition my rotation resets to normal state. The HTML and CSS are simple:
HTML
<span></span>Test
CSS
a {
text-decoration: none;
}
a span {
display: inline-block;
width: 25px;
}
a span:before {
content:'>';
font-size: 10px;
font-weight: bold;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
-ms-transition: all 0.5s;
-o-transition: all 0.5s;
transition: all 0.5s;
}
a:hover span:before {
margin-left: 55%;
-webkit-transform: rotate(-90deg);
}
The transition goes as expected except at the very end of the animation the rotation resets to normal state instead of persists. I've created a JSFiddle as an example. How do I keep my rotation to persist?
Try adding display: inline-block
like this:
a:hover span:before {
margin-left: 55%;
-webkit-transform: rotate(90deg);
display: inline-block;
}
fiddle.
Explanation.
The pseudo elements, like :before or :after are inline, by default, so they have issues with being transformed, thus you need to set them to display: block or display: inline-block.
Its Working Use this Method
Don't use margin for animation use translate istead.
for better smooth transitions
Demo
html
<span>></span>Test
css
a {
text-decoration: none;
}
a span {
display: inline-block;
width: 25px;
}
a span{
font-size: 10px;
font-weight: bold;
-webkit-transition: all 0.5s linear;
-moz-transition: all 0.5s linear;
-ms-transition: all 0.5s linear;
-o-transition: all 0.5s linear;
transition: all 0.5s linear;
}
a:hover span{
-webkit-transform: rotate(-90deg) translateX(50%);
-moz-transform: rotate(-90deg) translateX(50%);
-ms-transform: rotate(-90deg) translateX(50%);
-o-transform: rotate(-90deg) translateX(50%);
transform: rotate(-90deg) translateX(50%);
}
Related
I have a navbar. On hover of any of it menu item I want to have the exact same effect of border-bottom animation as in here (See how the border or menu items at the top-left animates when you hover them.)
I tried to find similar asked questions on stackoverflow and also on google but I didn't find anything helpful.
Any help is really appreciated.
Well, it was as easy as inspecting the web with the developer tools. What they do in that page is to create an element inside the menu using the :before pseudo-element. On hover they use CSS transforms (scale) to change the length.
jsfiddle.
span
{
display: inline-block;
padding: 6px 0px 4px;
margin: 0px 8px 0px;
position: relative;
}
span:before
{
content: '';
position: absolute;
width: 100%;
height: 0px;
border-bottom: 1px solid black;
bottom: 2px;
-webkit-transform: scaleX(0);
-ms-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: -webkit-transform 0.2s ease-in;
transition: transform 0.2s ease-in;
}
span:hover:before
{
-webkit-transform: scaleX(1);
-ms-transform: scaleX(1);
transform: scaleX(1);
}
You can't have the border a different length to the element that it surrounds. However you can achieve a similar effect using just CSS - with a pseudo element. How about something like the following:
div:after{
position:absolute;
bottom:0;
left:50%;
height:1px;
width:0%;
background-color:#444;
display:block;
content:'';
transition:0.3s;
}
div:hover:after{
left:0;
width:100%;
}
JSFiddle
Its not border-bottom, it is done using css pusedo element :before
.navigation li a::before {
position: absolute;
bottom: -1px;
left: 0;
content: "";
width: 100%;
height: 1px;
background-color: #fff;
display: block;
-webkit-transition: all 0.2s ease-in-out 0s;
-moz-transition: all 0.2s ease-in-out 0s;
transition: all 0.2s ease-in-out 0s;
-webkit-transform: scaleX(0);
-moz-transform: scaleX(0);
transform: scaleX(0);
}
.navigation li a::before {
-webkit-transform: scaleX(1);
-moz-transform: scaleX(1);
transform: scaleX(1);
}
This question already has answers here:
Translate x and y with a different timing functions?
(3 answers)
CSS Transition for only one type of transform?
(5 answers)
Closed 2 years ago.
I have property like this
transition: top .5s, transform .5s .5s;
And usually, for better performance, we should use only transform and opacity for animate.
It is possible to animate like this?
transition: transform(translateY) .5s, transform(rotate) .5s .5s;
document.querySelector(".burger").onclick = function(e) {toggleActive(e)};
function toggleActive({target}) {
target.classList.toggle('active')
}
span {
top: 50%;
transform: translateY(-50%);
transition: background-color 0.1s 0.5s;
}
span, span:before, span:after {
background-color: #555;
height: 5px;
width: 35px;
display: block;
border-radius: 5px;
position: absolute;
animation-duration: 3s;
animation-fill-mode: forwards;
}
span:before, span:after {
content: '';
}
.basic:before, .basic:after {
transition: transform 0.5s, top 0.5s 0.5s;
}
span:before {
top: 200%;
}
span:after {
top: -200%;
}
.basic.active {
background-color: rgba(0, 0, 0, 0);
}
.basic.active:before {
transform: rotate(-45deg);
}
.basic.active:after {
transform: rotate(45deg);
}
.basic.active:before, .basic.active:after {
top: 0;
transition: top 0.5s, transform 0.5s 0.5s;
}
<span class="burger basic"></span>
In this case, I did use top property. And I wanna transition the properties of transform.
I don't need any patches using JS. The only question is whether there is such a possibility at all. I might add that I originally use SCSS.
If you add more elements you can easily do it. I have also optimized the code to remove the background transition so we keep only transform transition:
document.querySelector(".burger").onclick = function(e) {
document.querySelector(".burger").classList.toggle('active')
};
.burger {
top: 50%;
transform: translateY(-50%);
transition: transform 0.5s;
background-color: #555;
height: 5px;
width: 35px;
position: absolute;
border-radius: 5px;
cursor: pointer;
}
.burger div:before {
content: '';
display: block;
height: 100%;
background-color: #555;
border-radius: 5px;
transition: transform 0.5s;
}
.burger div {
position: absolute;
height: 100%;
width: 100%;
transition: transform 0.5s 0.5s;
transform: translateY(-200%);
}
.burger div:last-child {
transform: translateY(200%);
}
.basic.active {
transform: translateY(-50%) rotate(-45deg);
transition: transform 0.5s 0.5s;
}
.basic.active div {
transform: translateY(0%);
transition: transform 0.5s;
}
.basic.active div:last-child::before {
transform: rotate(90deg);
transition: transform 0.5s 0.5s;
}
<div class="burger basic">
<div></div>
<div></div>
</div>
I'm trying to rotate the double angle bracket set as the content in an :after pseudo-element using the css transform value rotate(90deg) for a tab across the top of the screen. Here's the relevant code:
.header {
-moz-transition: top .5s ease;
-webkit-transition: top .5s ease;
-o-transition: top .5s ease;
transition: top .5s ease;
position: absolute;
left: 0;
right: 0;
top: -60px;
height: 80px;
background-color: #2d2;
}
.header.in-top {
top: 0;
}
.header-tab {
position: absolute;
bottom: 0;
width: 100%;
height: 20px;
text-align: center;
color: #000;
-moz-transition: color .5s ease;
-webkit-transition: color .5s ease;
-o-transition: color .5s ease;
transition: color .5s ease;
}
.header-tab:hover {
color: #e22;
}
.header-arrow:after {
font-size: 20px;
line-height: 1;
-moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-o-transform: rotate(90deg);
transform: rotate(90deg);
}
.header .header-arrow:after {
content: "\00bb";
}
.header.in-top .header-arrow:after {
content: "\00ab";
}
<div class="header">
<div class="header-tab" data-toggle="in-top">
<span class="header-arrow"></span>
</div>
</div>
The data-toggle attribute is used in JavaScript to toggle the in-top class in order to switch the direction of the double angle bracket as well as to expose the content of the header by bringing it down. The transform properties I have specified seem to do nothing though. Any solutions?
Use display: inline-block on the pseudo-element. Alternatively, inline-table or block should also work.
See jsFiddle.
Your pseudo-element is displayed inline by default, which makes it a nontransformable element. From the CSS Transforms Working Draft specification:
transformable element
A transformable element is an element in one of these categories:
an element whose layout is governed by the CSS box model which is either a block-level or atomic inline-level element, or whose ‘display’ property computes to ‘table-row’, ‘table-row-group’, ‘table-header-group’, ‘table-footer-group’, ‘table-cell’, or ‘table-caption’
You need to set the pseudo-element as a block or inline-block element:
.header-arrow:after {
display: block;
}
The specification says rotation should work on inline elements, but in WebKit based browsers it doesn't works: https://www.webkit.org/blog/130/css-transforms/
Rotate property will apply on pseudo-element(after/before) only when you will use display:inline-block; or display:inline-block; property in your class or selector.
.className:before{
-webkit-transform: rotateZ(180deg); /* Safari */
transform: rotateZ(180deg); /* Standard syntax */
display: inline-block;
}
I put an image on :after, with a translation on :hover. It makes other unrelated elements move on Chrome, with OS X (Firefox: unresponsive, and Safari : doesn't support transition effect)
I tried without transition, works fine.
I have this on several elements, and they all have this same problem as long as transition and :after are involved.
Here's the html:
See the project
and the css:
.btn-call-to-action {
background: #8e8287;
margin-bottom: 15px;
color: #f5f3e2;
padding: 10px 70px 10px 10px;
margin-top: 6px;
line-height: 1;
display: inline-block;
position: relative;
border-bottom: none;
border-radius: 2px;
white-space: nowrap; }
.btn-call-to-action:after {
content: url('../img/general-white-arrow.svg?1370787761');
position: relative;
display: inline-block;
position: absolute;
top: 8px;
width: 35px;
padding-left: 15px;
-webkit-transition: all 0.2s ease-in-out;
-moz-transition: all 0.2s ease-in-out;
-o-transition: all 0.2s ease-in-out;
-ms-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out; }
.btn-call-to-action:hover:after {
-webkit-transform: translatex(6px);
-moz-transform: translatex(6px);
-o-transform: translatex(6px);
-ms-transform: translatex(6px);
transform: translatex(6px); }
and the live version here.
I'm having an issue in chrome with a css3 transform rotate transition. The transition is working fine but just after it finishes the element shifts by a pixel. The other strange thing is that it only happens when the page is centered (margin:0 auto;). The bug is still there if you remove the transition as well.
You can see it happening here:
http://jsfiddle.net/MfUMd/1/
HTML:
<div class="wrap">
<img src="https://github.com/favicon.ico" class="target" alt="img"/>
</div>
<div class="wrap">
<div class="block"></div>
</div>
CSS:
.wrap {
margin:50px auto;
width: 100px;
}
.block {
width:30px;
height:30px;
background:black;
}
.target,.block {
display:block;
-webkit-transition: all 0.4s ease;
-moz-transition: all 0.4s ease;
-o-transition: all 0.4s ease;
transition: all 0.4s ease;
}
.target:hover,.block:hover {
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-o-transform: rotate(90deg);
-ms-transform: rotate(90deg);
}
Comment out the margin:0 auto; line to make it go away.
Anyone have any ideas of how to stop this while keeping the page centered?
I'm using Version 24.0.1312.57 on OSX 10.6.8
Cheers
Actually just add this to the site container which holds all the elements:
-webkit-backface-visibility: hidden;
Should fix it!
Gino
I had the same issue, I fixed it by adding the following to the css of the div that is using the transition:
-webkit-backface-visibility: hidden;
-webkit-transform: translateZ(0) scale(1.0, 1.0);
Backface is used for 3D-based transitions but if you are only using 2D there is no need for the extra stuff.
will-change: transform; on the element helped to me in 2022 (Chrome). No more 1px shift of the text inside the element after zoom animation.
there is something unusual in the relation between the body dimension and the structure of the transform. I don't in fact is because the fiddle iframe that contains the preview of the code.
Anyway, I will suggest this approach instead:
body{
width:100%;
float:left;
}
.wrap {
margin: 50px 45%;
width: 5%;
float: left;
}
.block {
width:30px;
height:30px;
background:black;
}
.target,.block {
-webkit-transition: all 0.4s ease;
-moz-transition: all 0.4s ease;
-o-transition: all 0.4s ease;
transition: all 0.4s ease;
}
.target:hover,.block:hover {
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-o-transform: rotate(90deg);
-ms-transform: rotate(90deg);
}
Here is the updated fiddle
For 3d transform use this instead:
-webkit-transform: perspective(1px) scale3d(1.1, 1.1, 1);
transform: perspective(1px) scale3d(1.1, 1.1, 1);