I have created an animation where a background image moves from left to the right. I want this animation to go diagonal so I've turned the div 45 degrees using: -webkit-transform: rotate(45deg);
The result looks like this fiddle
As you can see, the div is turned (red border), but I want the div not to rotate. So how can I keep the diagonal animation without rotating the div?
Thanks
ps for demo purposes I've only used the -webkit- prefix
ps2 I can only modify one div with the css, so adding another div is
not possible
You can use pseudo elements to accomplish what you want:
html:
<div id='test'></div>
css:
#test:before
{
content: "";
position: absolute;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
z-index: -1;
background: url(background.png) 0 0 repeat;
-webkit-transform: rotate(30deg);
-moz-transform: rotate(30deg);
-ms-transform: rotate(30deg);
-o-transform: rotate(30deg);
transform: rotate(30deg);
background-image: url("http://www.easyvectors.com/assets/images/vectors/afbig/green-left-double-arrows-set-clip-art.jpg");
background-repeat: repeat;
-moz-animation: swim 2s linear 0s infinite;
-webkit-animation: swim 2s linear 0s infinite;
-webkit-transform: rotate(45deg);
}
#test {
position: relative;
overflow: hidden;
width: 300px;
height:300px;
border: 3px solid red;
}
#-webkit-keyframes swim {
from { background-position: 200% 0, 0 0; }
to { background-position: 100% 0, 0 0; }
}
Fiddle
Check out this great article by Craig Buckler for more information.
Related
can someone help me to do this hover effect
it is a normal circle
and when passing over it I would like it to look that way and even for the circle to rotate
Thanks in advance
If I understand you correctly, here is one way you could make this work.
There are 3 elements to this; the image, the circle and the gap.
The circle is a div with a border-radius to round it out, and a border with the color of your choice.
The gap is a div that is the full height of the wrapper and the width of the intended gap. The div is given the same color as the background (white in this case - change to whatever you want). Then we apply a transform of -30deg to get the angle in your example.
The image is a div with a border-radius and is positioned in the middle of the wrapper.
The css then makes use of keyframes to add an animation to the gap div to make it rotate when you hover over the wrapper. This gives the illusion of the circle rotating.
.wrapper {
position: relative;
height: 350px;
width: 350px;
}
.wrapper .circle {
position: absolute;
height: 340px;
width: 340px;
border: 5px solid #00C17F;
border-radius: 50%;
}
.wrapper .gap {
position: absolute;
width: 100px;
height: 350px;
left: 125px;
background: white;
-ms-transform: rotate(-30deg);
-moz-transform: rotate(-30deg);
-webkit-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
transform: rotate(-30deg);
}
.wrapper:hover .gap {
display: block;
-webkit-animation: rotateCircle 20s linear infinite;
-moz-animation: rotateCircle 20s linear infinite;
-ms-animation: rotateCircle 20s linear infinite;
-o-animation: rotateCircle 20s linear infinite;
animation: rotateCircle 20s linear infinite;
}
.wrapper .image {
position: absolute;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/f/f2/Light_Work_%28Unsplash%29.jpg");
background-size: cover;
background-position: right;
border-radius: 50%;
top: 10%;
left: 10%;
height: 80%;
width: 80%;
}
#keyframes rotateCircle {
from {
-ms-transform: rotate(-30deg);
-moz-transform: rotate(-30deg);
-webkit-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
transform: rotate(-30deg);
}
to {
-ms-transform: rotate(330deg);
-moz-transform: rotate(330deg);
-webkit-transform: rotate(330deg);
-o-transform: rotate(330deg);
transform: rotate(330deg);
}
}
<div class="wrapper">
<div class="circle"></div>
<div class="gap"></div>
<div class="image"></div>
</div>
You can have just one HTML element. But you need 3 layers:
holds the green circle
holds the image
creates the gaps by overwriting part of the circle
Layer 3 can also be made to rotate on hover.
CSS allows you to attach before and after pseudo elements to elements such as divs (not to normal img elements though, hence we use a div).
This way we have our 3 layers. We use the div itself to display the green circle and above it (in z-index terms) we place a pseudo element which creates the gaps by having a conic gradient background image. This only turns up when the user hovers. The other pseudo element holds the image with z-index set so it is above the others and doesn't get affected by the rotating conic gradient.
Note that all units used here are relative so the code is responsive.
.circle {
--gap: 30deg; /* set this to what you want the gap to be */
--border: 2px; /* set this to what you want the width of the green in the border to be can be in vmin for example for full responsiveness */
position: relative;
border: solid green var(--border);
border-radius: 50%;
width: 50vmin;
height: 50vmin;
margin: 0;
padding: 0;
box-sizing: border-box;
}
.circle::before, .circle::after {
content: '';
border-radius: 50%;
position: absolute;
margin: 0;
padding: 0;
}
.circle::after {
/* position and center the image */
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
width: 70%;
height: 70%;
background-image: url(https://picsum.photos/id/0/400/400);
background-size: cover;
border-radius: 50%;
border-style: solid;
z-index: 2;
}
.circle:hover::before {
width: calc(100% + (3 * var(--border)));/* make it slightly bigger to make sure a 'stray' screen pixel does not get left out when the system converts part CSS px to screen pixels */
height: calc(100% + (3 * var(--border)));
top: calc(-1.5 * var(--border));
left: calc(-1.5 * var(--border));
z-index: 1;
background-image: conic-gradient(white 0deg, white var(--gap), transparent var(--gap), transparent 180deg, white 180deg, white calc(180deg + var(--gap)), transparent calc(180deg + var(--gap)), transparent 360deg);
animation: rotate 2s infinite linear;
}
#keyframes rotate {
to {
transform: rotate(360deg);
}
}
<div class="circle"></div>
In firefox pseudo elements are behind the div (this is what I wanted to achieve) but in chrome they are on top. Is this a bug in chrome? Anyone knows how to fix this? Adding z-index to the div didn't help me to solve this problem.
I've also tried to apply some styles to div:hover but then when I hover over the div element it falls behind pseudo elements (in Firefox, in Chrome pseudo elements are already on top).
Demo on codepen https://codepen.io/mariuszdaniel/pen/rzdyRV?editors=1100
#keyframes spin {
from {
transform: rotate(0turn)
translateY(-100%) translateY(50%)
rotate(1turn)
}
to {
transform: rotate(1turn)
translateY(-100%) translateY(50%)
rotate(0turn);
}
}
#keyframes spin-rev {
from {
transform: rotate(1turn)
translateY(-100%) translateY(50%)
rotate(0turn)
}
to {
transform: rotate(0turn)
translateY(-100%) translateY(50%)
rotate(1turn);
}
}
#keyframes glow {
from {
filter: blur(100px);
opacity: 0.8
}
to {
filter: blur(200px);
opacity: 0.4;
}
}
.path {
width:300px;
height: 300px;
padding: 20px;
margin: 100px auto;
border-radius: 50%;
background-image: url(https://unsplash.it/300);
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: relative;
transition: transform 0.5s, box-shadow 0.5s;
}
.path:hover {
transform: scale(1.25);
box-shadow: 0 0 50px 0 #3333;
}
.path::before, .path::after {
content: "";
position:aboslute;
display: block;
width: 75%;
height: 75%;
margin: 25% auto 0;
border-radius: 50%;
/*filter: blur(100px); */
/*opacity: 0.5;*/
}
.path::before {
/*mix-blend-mode: hue;*/
z-index: -200;
background-color: #21D4FD;
background-image: linear-gradient(19deg, #21D4FD 0%, #B721FF 100%);
animation: spin 9s infinite /*alternate*/ linear, glow 3s infinite alternate linear;
}
.path::after {
margin-top: -100%;
z-index: -100;
background-color: #08AEEA;
background-image: linear-gradient(0deg, #08AEEA 0%, #2AF598 100%);
animation: spin-rev 6s infinite /*alternate-reverse*/ linear, glow 6s infinite alternate linear;
}
<div class="path"></div>
The problem is that the transform property's value has multiple part like translate, scale etc.
This is a theoretical question about element, let's .loader that has transform:translate(10px, 10px) and in the animation I want to animate the scale property. In this case, the browser will not take the transform:translate(10px, 10px) and will take only the scale.
I am looking for a way around this problem.
Here is an example to this question. Please, keep attention that I'm not looking for an answer to this particular example (like: wrap the element or add the translate value to the animation definition) but a generic solution (if exist, of course).
.loading {
position: relative;
width: 100px;
height: 100px;
background: #eee;
}
.loading:before,
.loading:after {
content: "";
width: 50%;
height: 50%;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
background-color: #fff;
opacity: 0.6;
position: absolute;
top: 0;
left: 0;
/* the broswer doesn't take this */
transform: translate(100px, 300px);
-webkit-animation: bounce 2s infinite ease-in-out;
animation: bounce 2s infinite ease-in-out;
}
.loading:after {
-webkit-animation-delay: -1s;
animation-delay: -1s;
}
#keyframes bounce {
0%, 100% {
transform: scale(0);
-webkit-transform: scale(0);
}
50% {
transform: scale(1);
-webkit-transform: scale(1);
}
}
<div class="loading"></div>
Generally when you add an animation with changes to the transform property then the transforms that are specified in the base element should also be carried over to be present within the animation's keyframes also. That is, the new transforms (that are part of the animation) should be added over on top of the existing transform and not overwrite it. Below is how it should be done.
.loading {
position: relative;
width: 200px;
height: 200px;
background: #eee;
}
.loading:before,
.loading:after {
content: "";
width: 50%;
height: 50%;
border-radius: 50%;
background-color: #fff;
opacity: 0.6;
position: absolute;
top: 0;
left: 0;
transform: translate(100px, 300px);
animation: bounce 2s infinite ease-in-out;
}
.loading:after {
animation-delay: -1s;
}
#keyframes bounce {
0%, 100% {
transform: scale(0) translate(100px, 300px);
}
50% {
transform: scale(1) translate(100px, 300px);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="loading"></div>
I wrote a similar answer here to a question about adding multiple animations on an element with each of those animations modifying the transform property's values independent of the other. I am linking it here only for reference and don't think they are duplicates.
Having said the above, adding the the original transform to each animation's kefyrames is not possible when you are trying to create animation libraries or trying to split each animation into a separate class. Say for example, you want to add the same bounce animation to multiple elements and each of them have a different initial transform setting then it becomes impossible to add it to animation's keyframe.
In such cases, you can still achieve the desired output using CSS but it would be very difficult (almost impossible in my opinion) to get it done with a single element.
What options do you have? Well, one option is for you to add the animation on a wrapper element.
.loading-wrapper {
position: relative;
width: 200px;
height: 200px;
background: #eee;
}
.loading-before, .loading-after {
position: absolute;
width: 50%;
height: 50%;
top: 0px;
left: 0px;
animation: bounce 2s infinite ease-in-out;
}
.loading-before:before,.loading-after:before {
content: "";
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #fff;
opacity: 0.6;
position: absolute;
top: 0;
left: 0;
transform: translate(100px, 300px);
}
.loading-after {
animation-delay: -1s;
}
#keyframes bounce {
0%, 100% {
transform: scale(0);
}
50% {
transform: scale(1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="loading-wrapper">
<div class="loading-before"></div>
<div class="loading-after"></div>
</div>
The solution is quite generic and you can apply it to almost all such cases. The drawback is that if you want to stack multiple such transformations then you'd likely end up with multiple such wrappers. There is no pure CSS way other than adding original transformations within the animation's keyframes also.
The below snippet is another sample.
.move-n-scale {
position: relative;
height: 100px;
width: 100px;
background: sandybrown;
border: 1px solid chocolate;
transform: scale(0.5);
animation: move 1s linear infinite alternate-reverse;
}
.move {
position: relative;
display: inline-block;
animation: move-only 1s linear infinite alternate-reverse;
}
.scale {
position: absolute;
height: 100px;
width: 100px;
top: 0px;
left: 0px;
background: sandybrown;
border: 1px solid chocolate;
transform: scale(0.5);
}
#keyframes move {
from {
transform: translateX(0px) scale(0.5);
}
to {
transform: translateX(300px) scale(0.5);
}
}
#keyframes move-only {
from {
transform: translateX(0px);
}
to {
transform: translateX(300px);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='move-n-scale'></div>
<div class='move'>
<div class='scale'></div>
</div>
Note: Just to clarify, I did notice that you had mentioned about not wanting a solution which is very specific to this problem like wrap it etc. But, I had still added this solution as an answer because it is the only generic solution which I am aware of. I had added the second snippet only to show that is is indeed generic.
You can delete the translate(100px, 300px); in .loading:after, then set the translate(100px, 300px) in #keyframes, like follows:
#keyframes bounce {
0%,
100% {
transform: scale(0)translate(100px, 300px);
-webkit-transform: scale(0)translate(100px, 300px);
}
50% {
transform: scale(1)translate(100px, 300px);
;
-webkit-transform: scale(1)translate(100px, 300px);
}
}
I'm trying out a CSS3 animation on a background image. Everything's working well, the problem is that on Chrome the text ends up being blurred when the animation is in progress:
During Animation:
Turning off the animation:
As you can see the text rendering is fine when the animation is turned off, I know there's the usual issue with text rendering but I can't understand why the rendering is poor on Chrome when the animation is in progress. I'm not sure there's anything I can do about it really. I've tested the animation on Firefox and IE and it's ok. By the way I'm working on Windows.
Firefox:
IE:
EDIT
.bg-div {
position: fixed;
width: 110%;
height: 110%;
transform: translate(-5%, -5%);
-moz-transform: translate(-5%, -5%) rotate(0.02deg); /* rotation to solve choppy animation on Firefox */
-ms-transform: translate(-5%, -5%);
background-image: url('images/colour-test.jpg');
background-size: cover;
-webkit-animation: bg-animation 10s linear infinite;
-moz-animation: bg-animation 10s linear infinite;
-ms-animation: bg-animation 10s linear infinite;
}
#-webkit-keyframes bg-animation {
25% { transform: translate(-5.5%, -5.5%); }
50% { transform: translate(-5.3%, -4.9%); }
75% { transform: translate(-4.8%, -4.3%); }
}
#-moz-keyframes bg-animation {
25% { -moz-transform: translate(-5.5%, -5.5%) rotate(0.02deg); }
50% { -moz-transform: translate(-5.3%, -4.9%) rotate(0.02deg); }
75% { -moz-transform: translate(-4.8%, -4.3%) rotate(0.02deg); }
}
#-ms-keyframes bg-animation {
25% { -ms-transform: translate(-5.5%, -5.5%); }
50% { -ms-transform: translate(-5.3%, -4.9%); }
75% { -ms-transform: translate(-4.8%, -4.3%); }
}
.content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50%;
height: 65%;
text-align: center;
}
After reading the question and answer posted in the comments I've tried to adding -webkit-font-smoothing: subpixel-antialiased; to .bg-div but that didn't make any difference.
EDIT 2
Okay so this is a bit of a weird one, during the animation apparently the position: fixed is making the text blurry. I don't know how that is possible, anyway once I removed the position: fixed and the background was animating the text was displayed correctly. It's still not what I want because I need the background to be fixed.
In my testing, the problem is fixed if the transform is not used on .content. Luckily, you don't need to use transform to position your content div.
Use this margin: auto trick to position instead
Using this method, you do not need to use transform: translate(-50%, -50%)
The content is centered with the combination of top, right, bottom, left, margin: auto and the percentage width and height.
.content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 50%;
height: 65%;
text-align: center;
}
Working Example
body { margin: 0 auto; width: 500px }
.bg-div {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 800px;
height: 800px;
transform: translate(-5%, -5%);
background: url('http://www.placehold.it/800') no-repeat;
-webkit-animation: bg-animation 2s linear infinite;
animation: bg-animation 2s linear infinite;
}
#-webkit-keyframes bg-animation {
0% {
transform: translate(-5.5%, -5.5%);
}
50% {
transform: translate(-5%, -5%);
}
100% {
transform: translate(-5.5%, -5.5%);
}
}
#keyframes bg-animation {
0% {
transform: translate(-5.5%, -5.5%);
}
50% {
transform: translate(-5%, -5%);
}
100% {
transform: translate(-5.5%, -5.5%);
}
}
.content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 50%;
height: 65%;
text-align: center;
}
<div class="bg-div"></div>
<div class="content">
<h1>This looks better</h1>
<input value="Text" />
</div>
I've just started to work on a pure css set of social icons. Everything is going pretty smooth but I can't get this half circle shadow to rotate correctly.
The transition seems to be working correctly but the positioning of the shadow is not correct. It may be due to the axis point it is rotating on but it seems to be correct. Without any transition I can get the shadow aligned correctly with,
top: 7px;
right: 15px;
but the shadow's parent is positioned relative and should keep the shadow inside of it without problems. I also tried top, left 5px since there is a 5px border on it but this also did not work.
Here is the css for the shadow:
.shadow {
height: 45px;
width: 100%;
overflow: hidden;
position: absolute;
top: 7px;
right: 15px;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
transition: all 0.6s ease;
-webkit-transition: all 0.6s ease;
-moz-transition: all 0.6s ease;
}
.shadow:before {
content: "";
width: 90px;
height: 90px;
position: absolute;
display: block;
border-radius: 50%;
background: rgba(0, 0, 0, 0.1);
}
.icon:hover .shadow {
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
bottom: 7px;
left: 15px;
}
My Test Runs
Shadow without top, left, right, and bottom used: Demo
Full set of icons with top, left, right, and bottom used: Demo
With the use of transform-origin: Demo
I do know why, on the full set of icons, it is transitioning so poorly but I am unsure of how to align this shadow correctly. Any ideas on how I can get this shadow to rotate inside of the icon correctly?
You are fixing with margins what you should fix with transform origin
CSS
.shadow {
height: 45px;
width: 100%;
overflow: hidden;
position: absolute;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
transition: all 0.6s ease;
-webkit-transition: all 0.6s ease;
-moz-transition: all 0.6s ease;
-webkit-transform-origin: center bottom;
-moz-transform-origin: center bottom;
transform-origin: center bottom;
}
.icon:hover .shadow {
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
}
fiddle
I have removed left and top, and added transform origin. This must be at the bottom because you have only half a circle, and so the circle center is at the bottom.
Nice icons! You were very close. You just needed the hover margin to adjust from the same side.
http://jsfiddle.net/SVHny/7/
.icon:hover .shadow {
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
bottom: 7px;
right: -15px;
}