So, I was trying to get an image to, when hovered over, spin 360 degrees and scale up by 1.4, all with its centre staying in place. I tried this:
.logo img[data-v-4fbac4e1] {
width: 50px;
height: 50px;
content: url(https://i.imgur.com/txz1IXI.png);
transition: width 2.0s, height 2.0s, transform 2.0s;
}
with this:
.logo img[data-v-4fbac4e1]:hover{
width: 65px;
height: 65px;
transform: rotate(360deg);
}
and it works fine, but it moves off-centre as it expands. How do I make sure the width and height increase from the centre so it stays in the same place? Sorry if this seems elementary, I'm new to CSS.
Edit: the part of the HTML I'm using looks like this:
<a data-v-4fbac4e1 href="/home" class="logo">
<img data-v-4fbac4e1 src="/img/icons/icon.svg">
</a>
If more is required I can add it, but this is the HTML for the image I'm trying to transform.
Since I'm not entirely sure what you mean, point to which is your culprit and we'll get you sorted out but here's some examples of the differences between techniques.
img, div {
display: inline-block;
margin: 1rem;
height: 10rem;
width: 10rem;
}
.fancy-img1, .fancy-img3 {
object-fit: cover;
outline: red 2px solid;
}
.fancy-img2, .fancy-img4 {
background: url(https://picsum.photos/200) no-repeat center center / cover;
outline: blue 2px solid;
}
/* grow by height value change transition */
.fancy-img1 {
transition: transform .5s, height .5s;
}
.fancy-img2 {
transition: transform .5s, height .5s;
}
.fancy-img1:hover, .fancy-img2:hover {
transform: rotate(360deg);
height: 15rem;
}
/* Scale with transition */
.fancy-img3 {
transition: transform .5s;
}
.fancy-img3:hover {
transform: scaleY(1.5) rotate(360deg);
}
/* Scale with keyframes */
#keyframes spinGrow {
to { transform: scaleY(1.5) rotate(360deg); }
}
.fancy-img4:hover {
animation: spinGrow .5s forwards;
}
<h2>Are you talking about transition height which cause the jumpy effect?</h2>
<img class="fancy-img1" src="https://picsum.photos/200">
<div class="fancy-img2"></div>
<h2>Or actually scale so it remains in its original position?</h2>
<img class="fancy-img3" src="https://picsum.photos/200">
<div class="fancy-img4"></div>
Related
Long story made short I am trying to work on a page that will be showing a playing card that I want to animate flipping over to the back side and back again at certain points. So far I've been using a lot of the code from this useful blog post to do so: https://manjitkarve.com/posts/card-flip-interaction/
What I'm trying to add on now is a clip-path as the majority of my card images are not 'clean' and have some jank white lines around the image and using clip-path in CSS seemed like the cleanest way to nail this. And so far isolated on its own it is doing the job swimmingly.
However with the clip-path added in, my card flip transitions are messed up. As an example: If I am sitting on the 'front' face of the card and ask it to flip to the back, it flips to a mirrored version of the front face instead. Once I take clip-path out, it's back to normal.
There's a LOT of moving parts to my code now but I'll post what I can/what's relevant. As an addition note, I'm also using the SWUP JS library in here but that functionality is working fine and best I can tell is not interfering with this currently. If I call these card transitions manually outside of SWUP, I get the same behavior:
HTML:
<main id="swup">
<div id="swup-card-img card_img_overlay" class="card-left-half card transition-flip center">
<div class="front face" style="background-image:url('{{ card.card_image.url }}')"></div>
<div class="back face" style="background-image:url('{% static 'img/fow_cardback.png' %}')"></div>
</div>
</main>
CSS:
.transition-flip {
transition: transform 1.0s;
transform-style: preserve-3d;
}
.transition-flip .card .front {
transform: rotateX(0deg);
}
.transition-flip .card .back {
transform: rotateX(180deg);
}
html.is-animating .transition-flip {
transform: rotateY(180deg);
transition: transform 1.0s;
}
html.is-leaving .transition-flip {
transform: rotateY(180deg);
transition: transform 1.0s;
}
.card {
/* Card height to width ratio is 1.396 rounded */
width: 50vw;
height: 69.8vw;
position: relative;
perspective: 100vw;
perspective-origin: 50% 50%;
transform-style: preserve-3d;
display: inline-block;
clip-path: inset(0.3% 0.2% 0.0% 0.2% round 3.9%);
background: rgba(0, 0, 0, 1.0);
}
.card .face {
backface-visibility: hidden;
position: absolute;
width: 100%;
height: 100%;
transition: transform 0.35s cubic-bezier(0.13, 1.03, 0.39, 0.98), box-shadow 0.35s cubic-bezier(0.13, 1.03, 0.39, 0.98), border-width 0.35s cubic-bezier(0.13, 1.03, 0.39, 0.98);
box-shadow: 0px 1.2vw 4vw -1vw rgba(0, 0, 0, 0.6);
background-position: 0 0;
background-size: 50vw;
background-repeat: no-repeat;
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 1.1vw;
}
.card .front {
}
.card .back {
transform: rotateY(180deg);
transform: rotateX(180deg);
}
.center {
margin:0 auto;
}
I am trying to make a loading animation. I am using css transition to transition into the loading by scaling and then using animation to scale out the x axis. But when I try to transition back to the original state it doesn't use the transition anymore it just snaps back. I could use animation for the whole thing but I want to account for the page continuing to load so I don't want to have to write extra javascript logic to handle it. It would be nice if It would just transition on its own.
When you click the following snippet the first time it works fine. But when you click it again it just snaps back to its original state and doesn't use the transition. If you use a different property like opacity in the animation part then it works fine so I'm assuming there is something with the browser not recognizing the current scaled value. Is this a bug or am I doing something wrong?
document.querySelector('.wrapper').addEventListener('click', () => {
document.querySelector('.wrapper').classList.toggle('loading')
})
.wrapper{
position:fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.wrapper > div{
color: white;
display:flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background: blue;
transition: transform 500ms ease-out;
transform: scale(1);
}
.wrapper.loading > div{
transform: scale(0.2, 0.002);
animation: loading 1000ms ease-out infinite;
animation-delay: 500ms;
}
#keyframes loading {
0%{
transform: scale(0.2, 0.002)
}
50%{
transform: scale(0.5, 0.002)
}
100%{
transform: scale(0.2, 0.002)
}
}
<div class="wrapper">
<div>click me</div>
</div>
TL;DR
I believe that this happens because CSS transition eventually gives a class two states and transitions between them, when you remove your class you don't change its state, you remove it. my solution would be to add another class to set it back.
CSS transitions work by defining two states for the object using CSS. In your case, you define how the object looks when it has the class "loading" and you define how it looks when it doesn't have the class "saved" (it's normal look). When you remove the class "loading", it will transition to the other state according to the transition settings in place for the object without the "loading" class.
If the CSS transition settings apply to the object (without the "loading" class), then they will apply to both transitions.
your transition CSS settings only apply to .saved and thus when you remove it, there are no controls to specify a CSS setting. You may want to add another class ".fade" that you leave on the object all the time and you can specify your CSS transition settings on that class so they are always in effect.
I don't know a pure css fix for this.
But you can add a different class with a animation that restores to what it was before with JS
const wrapper = document.querySelector(".wrapper");
wrapper.onclick = () => {
if ([...wrapper.classList].includes("loading")) {
wrapper.classList.add("restore");
} else {
wrapper.classList.remove("restore");
}
wrapper.classList.toggle("loading");
};
.wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.wrapper>div {
color: white;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background: blue;
animation: none;
transform: scale(1);
transition: transform 500ms ease-out;
}
.wrapper.restore>div {
animation: restore 500ms ease-out;
}
.wrapper.loading>div {
transform: scale(0.2, 0.002);
animation: loading 1000ms 500ms ease-out infinite;
}
#keyframes restore {
0% {
transform: scale(0.2, 0.002);
}
100% {
transform: scale(1);
}
}
#keyframes loading {
0% {
transform: scale(0.2, 0.002)
}
50% {
transform: scale(0.5, 0.002)
}
100% {
transform: scale(0.2, 0.002)
}
}
<div class="wrapper">
<div>click me</div>
</div>
You can use animation iteration count property:
div {
animation-iteration-count: 2;
}
or use fill mode to freeze the animation at the end:
-webkit-animation-fill-mode: forwards;
I have a basic setup. When I increase the height, I get a smooth increase. When decreased, I should get a smooth decrease but instead a sharp decrease.
<div className="foo <!-- -->">Hey</div>
You may have noticed className and <!-- -->, I'm using react. <!-- --> gets replaced with the class to decrease the height.
// SCSS
.foo {
height 400px;
// background props
transition: all 250ms ease-out
}
.foo.decreaseClass {
height: 40px;
transition: all 250ms ease-in
}
When the new class is attached, the div becomes
<div className="foo decreaseClass">Hey</div>
How to get both transitions down/up?
It's because you're not properly closing the height declaration in .foo. You're using a comma instead of a semi-colon, rendering both height and transition declarations invalid. Also note the same declaration should contain a colon between the style property name and its value (height: 400px;).
Therefore, your element only has defined height and transition only when having both classes.
See it working:
document.querySelector('.foo').addEventListener('click', function(event) {
event.target.classList.toggle('decreaseClass')
})
.foo {
height: 200px;
transition: all 250ms ease-out;
border: 1px solid
}
.foo.decreaseClass {
height: 40px;
transition-timing-function: ease-in
}
<div class="foo">Hey</div>
Use CSS #keyframe animation and alternate properties. infinite is added just for demo purposes. Instead of height I added transform:scaleY(1) to (10).
Demo
body {
overflow: hidden
}
.test {
width: 200px;
margin: 10px;
background: red;
font-size: 32px;
text-align: center;
color: white
}
.B {
height: 40px;
animation: animB 1s alternate infinite;
transform-origin: top;
}
#keyframes animB {
0% {
transform: scaleY(1);
}
100% {
transform: scaleY(10);
}
}
<div class='test B'>TEST</div>
Hi i'm just a student I just wanna know if its possible to combine hover, transition, and transform by just using css.
How can transformed image transitioned back to it's original size and shape when hovered?
<html>
<style>
.sample {
display: inline-block;
border: 0px solid #fff;
margin: 10px;
overflow: hidden;
height: 500px;
width: 140px;
transform: rotate(0deg);
webkit-transition: 0.8s;
transition: 0.7s;
}
.sample img {
display: block;
transform: rotate(2deg);
transform-origin: 200% -600%;
}
.sample img:hover {
width: 600px;
height: 600px;
transform: rotate(0deg);
transform-origin: 0% 0%;
-webkit-transition-timing-function: ease-in-out;
}
</style>
<body>
<div class="sample">
<img src="http://www.freegreatpicture.com/files/39/1264-tree.jpg" height="600" width="600">
</div>
</body>
</html>
If you only define the CSS "transformed" rules in the hover pseudo-class, then when the image is no longer being hovered-over it will automatically transition back to its original state.
Here is a simplified example using part of your code (I changed the image to the Wikipedia logo since your image was coming up broken):
.sample img {
transform: rotate(30deg);
transition: ease-in-out 700ms;
}
.sample img:hover {
transform: rotate(0deg);
}
<div class="sample">
<img src="https://en.wikipedia.org/static/images/project-logos/enwiki.png">
</div>
The hover pseudo-class is an "active state class", meaning it only comes into play while that action is taking place (i.e., the pointer is hovered over the element).
If you want to include special easing and timing rules on the change from default state to hovered state then include the transition property in the default rule. You can specify lengths of time over which the transition takes place so the change can be more "animated". You'll notice that in the example above I stretched the rotation to 700ms so you can see it turning when hovered, then turning back when no longer hovered.
I have a wordpress website and I'd like to add some features that my current theme doesn't offer. I'd like the 3 images in the "Pages" section to reduce in size or switch to a different image (same content, smaller resolution) so as to appear smaller then you hover over it. I've managed to accomplish this with a custom HTML page, adding ID's to the images and then adding a version of this to my style.css for each image
#techbutton {
display: block;
width: 125px;
height: 125px;
background: url("http://rafsk.co.uk/wp-content/uploads/2015/10/Logo21-e1445171629993.png") no-repeat 0 0;
}
#techbutton:hover {
background: url("http://rafsk.co.uk/wp-content/uploads/2015/10/Logo2-hover-e1445296643552.png") no-repeat 0 0;
}
#techbutton span {
position: absolute;
top: -999em;
}
After uploading the custom HTML to my server I realised that instead of just overriding the homepage of rafsk.co.uk it also overrode the homepages of all my subdomains.
So how can I do this?
You could do this with a css transform, that would be the easiest way, and you can apply it to all three with a class instead of an id (which should only be used once per page):
So first give the same class to all of the images (meaning to the actual image tag, like <img class="imageclass" src="blah.png" />), and use this in your css:
.imageclass {
display: block;
width: 125px;
height: 125px;
transform: scale(1,1);
}
.imageclass:hover {
transform: scale(0.9,0.9);
}
You could then add a css transition effect if you want it to be smoother:
.imageclass {
display: block;
width: 125px;
height: 125px;
transform: scale(1,1);
transition: transform 0.6s ease-in-out;
}
.imageclass:hover {
transform: scale(0.9,0.9);
}
Here is a working example:
https://jsfiddle.net/f9teea7L/
ALTERNATIVE OPTION #1:
If you can't edit the HTML and can only get an image into the div through the background, you could try adding a background-size property like this. Be aware though that it won't work in IE 8 or lower:
#techbutton {
display: block;
background-image: url('http://vignette1.wikia.nocookie.net/deadliestfiction/images/d/d5/2138464123_1360632315.jpg/revision/latest?cb=20140513035922');
background-size: 100%,100%;
width: 125px;
height: 125px;
transform: scale(1,1);
transition: transform 0.6s ease-in-out;
}
#techbutton:hover {
transform: scale(0.9,0.9);
}
Working Example: https://jsfiddle.net/azx962a9/
ALTERNATIVE OPTION #2:
I've looked at your site though and if I'm understanding what you want to do, it seems to me that simply adding this to your css should work...:
.service-icon {
transform: scale(1,1);
transition: transform 0.6s ease-in-out;
}
.service-icon:hover {
transform: scale(0.9,0.9);
}