How to move a skewed div - css

I am trying to move a skewed div from top left off screen, through the screen, to bottom right off screen. The effect I am trying to get is that it looks like a parallelogram appears from somewhere up and to the left, and it slowly moves through the screen in a downwards and rightwards motion and then off the screen to the bottom.
Right now I have this index.html:
<html>
<head>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div class="div1" id="one"></div>
</body>
</html>
And here is my index.css:
div {
animation: rotate-all 2s 0 infinite linear alternate;
}
.div1 {
width: 100px;
height: 1000px;
transform: skew(20deg);
background-color: gray;
position: relative;
margin: auto;
animation-name: down;
animation-duration: 4s;
animation-iteration-count: infinite ;
}
#one {
top: 150px;
}
#keyframes down {
0% {
transform: translate(-200px, -1000px);
transform: skew(20deg);
}
100% {
transform: translate(250px, 750px);
}
}
I have two problems:
First, it is changing shape from the skewed shape (looks like a "\") to a unskewed one (looks like a "|"). If I try to add a skew in my 100% keyframe, then it does not move any more, it just stays in the same place. I tried both orders skew then translate / translate then skew.
Second, it does not seem to start above the screen, but right in the middle of the screen.
Appreciate any advice.

You were overwriting the transform property. Transform accepts multiple styles, separated by spaces. If you add the transform property twice, it will overwrite the first one. Just put the translate and skew on the same line both times and it will work.
For the second part, translate it by percents (relative to itself) rather than pixels (absolute measures).
div {
animation: rotate-all 2s 0 infinite linear alternate;
}
.div1 {
width: 100px;
height: 1000px;
transform: skew(20deg);
background-color: gray;
position: relative;
margin: auto;
animation-name: down;
animation-duration: 4s;
animation-iteration-count: infinite ;
}
#one {
top: 150px;
}
#keyframes down {
0% {
transform: translate(-200%, -200%) skew(20deg);
}
100% {
transform: translate(250px, 750px) skew(20deg);
}
}
<div class="div1" id="one"></div>

Related

How can I stop an animation without to reset the spinning rotation in CSS (example explains it best)

I have a little noobish CSS question If someone could share some free time to help. what I want to do is the div to stop and freeze at the position whenever I leave (hover off) my cursor, and not reset to his fixed starting position.
<script>
.rotatingDiv {
width: 50px;
height: 30px;
background-color: red;
margin: auto;
margin-top: 10rem;
cursor: pointer;
}
.rotatingDiv:hover {
animation: spin 4s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</script>
<body>
<div class="rotatingDiv"> </div>
</body>
as seen on the example the div keeps reseting to the starting position which is 0deg (default) on mouse-out, so what I want to achieve is for the div to freeze at the exact degree whenever I leave my cursor (mouse out/ hover off) from the div.
I think you wanted this thing it would be work
.rotatingDiv {
width: 50px;
height: 30px;
background-color: red;
margin: auto;
margin-top: 10rem;
cursor: pointer;
animation: spin 4s linear infinite;
animation-play-state: paused;
}
.rotatingDiv:hover {
animation: spin 4s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<body>
<div class="rotatingDiv"> </div>
</body>

How can you use CSS to animate a rolling element across the screen repeatedly?

This is my first time asking a question on here and I've found questions that are somewhat similar, but haven't worked for my issue.
I am trying to spin a word across the screen from off-screen left to off-screen right. The center of the word should be it's rotation point (ie word spins in place from left side of screen to right). I have tried using variations of translateX and rotate, but it either rotates in place or moves left to right. When it does move from the left to right off the screen, it keeps extending the bounds of my screen and stretching it before it loops back to the left side. Any ideas how I can solve this? Seems simple, but I'm terrible with animations.
.move {
position: absolute;
animation: moveword 10s infinite linear;
}
.spin {
position: absolute;
animation: spin 7s infinite linear;
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#keyframes moveword {
from {
left: -10%;
}
to {
left: 95%;
}
}
Based on code that you provide, I assume you could make something like this.
overflow: hidden needs to be applied to separate element, not the <body> because it restricts scrolling.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.page {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.word {
position: absolute;
top: 5px;
left: 5px;
animation: word-anim 10s infinite linear;
}
#keyframes word-anim {
0% {
transform: translateX(0px) rotateZ(0deg);
}
70% {
transform: translateX(70vw) rotateZ(360deg);
}
100% {
transform: translateX(100vw) rotateZ(360deg);
}
}
<div class="page">
<span class="word">A word</span>
</div>

Why is CSS position attribute affecting a rotation animation?

I'm working on a website (that I didn't design, someone else gave me the HTML/CSS) as a developer and We've got a nice spinner animation for async loading components. It's forever-spinning animation is defined by this CSS rule:
animation: spinning 1s infinite linear; (it has also vendor prefix versions but it's irrelevant).
The spinning animation is defined as:
#keyframes spinning {
0% { transform: rotate(0); }
100% { transform: rotate(360deg); }
}
Our designer has put a position: absolute !important attribute to the spinning element. I was trying to position it inside some other element and I've thought that attribute was irrelevant. As soon as I removed position: absolute, the spinner stopped spinning. When I added it again, spinner started spinning again.
I've tried other position values too, it seems that absolute and fixed are working okay (in regards to spinning animation) while relative and static cause the animation to stop.
Why would CSS position attribute affect a spinner animation?
Here is a snippet reproducing the problem:
#keyframes spinning {
0% { transform: rotate(0); }
100% { transform: rotate(360deg); }
}
#first{
position: absolute;
}
#second{
position: relative; /* or don't specify it at all */
}
<div style='background:yellow;width:400px;height:100px;'>
<span id='first' style='animation:spinning 1s infinite linear'>hello</span>
</div>
<div style='background:lime;width:400px;height:100px;'>
<span id='second' style='animation:spinning 1s infinite linear'>hello</span>
</div>
It's because a span is an inline-element by default and so is not affected by transforms.
Setting the position to absolute imparts a block formatting to the span.
Just add display:inline-block:
#keyframes spinning {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
div.one {
background: yellow;
width: 400px;
height: 100px;
}
div.two {
background: lime;
width: 400px;
height: 100px;
}
#first {
position: absolute;
animation: spinning 1s infinite linear
}
#second {
position: relative;
/* or don't specify it at all */
animation: spinning 1s infinite linear;
display: inline-block;
}
<div class="one">
<span id='first'>hello</span>
</div>
<div class="two">
<span id='second'>hello</span>
</div>

How can I place image just left outside visible part of page before animation start?

I want to place my image left outside of page how to do it?
+-------------------+
| visible page part |
image -> | |
+-------------------+
Finally I want to move image inside page.
+-------------------+
| visible page part |
| image inside page |
+-------------------+
You can use either negative margin or translateX transform to achieve this. The below snippet has an example for both approaches.
One thing to note is that the two methods work a bit differently even though their end output is similar. While translateX(-100%) moves element to the left (on the X-axis) by as many pixels as the width of the image, margin-left: -100% moves the image by as many pixels as the width of the container of the image. So, if the emphasis is on just left outside the visible part then using translateX(-100%) is more suitable.
/* using negative margins */
.margin {
margin-left: -100%;
animation: marginmove 1s 3s forwards;
}
#keyframes marginmove {
from {
margin-left: -100%;
}
to {
margin-left: 0%;
}
}
/* using translate transforms */
.translate {
transform: translateX(-100%);
animation: translatemove 2s 3s forwards;
}
#keyframes translatemove {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0%);
}
}
/* Just for demo */
body {
max-width: 300px;
margin: 0 auto;
padding: 0;
border: 1px solid;
}
html,
body {
overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div>Test content</div>
<img src="http://lorempixel.com/100/100/nature/1" class="margin" />
<div>Test content</div>
<img src="http://lorempixel.com/100/100/nature/2" class="translate" />
Note: As mentioned in comments, if there is a chance that the page's width can become lesser than the viewport's width then it would be imperative to add overflow: hidden to the root/parent element (as applicable) to prevent the image from showing up outside the page's left border.
You can adapt the above answer to work even when the image is part of a centered column which has equal margins on either sides. Below is a sample snippet to help you:
/* using negative margins */
.margin {
margin-left: -100%;
margin-right: 0%;
animation: marginmove 1s 3s forwards;
}
#keyframes marginmove {
from {
margin-left: -100%;
}
to {
margin-left: 0%;
}
}
/* using translate transforms */
.translate {
transform: translateX(-100%);
animation: translatemove 1s 3s forwards;
}
#keyframes translatemove {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0%);
}
}
/* Just for demo */
.container {
width: 300px;
margin: 0 auto;
border: 1px solid;
overflow: hidden;
}
.container > div{
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='container'>
<div>Centered column</div>
<img src="http://lorempixel.com/300/100/nature/1" class="margin" />
</div>
<div class='container'>
<div>Centered column</div>
<img src="http://lorempixel.com/300/100/nature/2" class="translate" />
</div>

CSS animation: Difference between left:100% and translate(100%)

I have read about how using translate has better performance, but it seems they behave slightly differently: using left:100% moves the animated object all the way to the end of the screen, whereas translate(100%) only moves the animated object as far as its length. That is, it moves 100% of the screen versus 100% of the object.
Can explain why this is, and what can be done to reproduce the same behavior when using translate?
You can see a demo here: http://jsfiddle.net/32VJV/1/
.slide_1 {
top: 0px;
left:0%;
position: absolute;
overflow: hidden;
font-size: 30px;
}
.slide_1 {
-webkit-animation: slide 3s infinite;
-webkit-animation-delay: 0s;
-webkit-animation-fill-mode:forwards;
-webkit-transform-origin: 0% 0%;
}
.slide_2 {
top: 25px;
left:0%;
position: absolute;
overflow: hidden;
font-size: 30px;
}
.slide_2 {
-webkit-animation: slide2 3s infinite;
-webkit-animation-delay: 0s;
-webkit-animation-fill-mode:forwards;
-webkit-transform-origin: 0% 0%;
}
#-webkit-keyframes slide {
0% {
-webkit-transform: translate(0%);
}
50% {
-webkit-transform: translate(100%);
}
100% {
-webkit-transform: translate(0%);
}
}
#-webkit-keyframes slide2 {
0% {
left 0%;
}
50% {
left:100%;
}
100% {
left:0%;
}
}
<div style="font-size:18px;">
<div class=""> <span class="slide_1" id="dimensions">ABC</span> <span class="slide_2" id="dimensions">ABC</span>
</div>
</div>
The difference between the two is that animating a property like left will keep the element in the flow of the document whereas translate does not.
For more information on why you might use one or the other, Paul Irish has an excellent write up (with links to more information): Why Moving Elements With Translate() Is Better Than Pos:abs Top/left
There's also a lot of great information on browser performance at jankfree.org
Solution for the translate animation: make the element as wide as the window:
Example
slide_1 {
top: 0px;
left:0%;
right: 0;
position: absolute;
overflow: hidden;
font-size: 30px;
}
An interesting exercise: Open your devtools and what what happens when you activate one animation at a time.
In Chrome:
The translate animation has basically nothing going on except a periodic GC
The Left animation you will see repeatedly:
Recalculate Style
Layout
Pain Setup
Paint
Composite Layers
In this case, the overhead it pretty small, but that can change quickly depending on what is being moved around the screen.

Resources