How can I "tranform:translate" relative to a previous translate? - css

I have the following working code which I am attempting to simplify:
[tt] {
position: relative;
}
[tt]::after {
bottom: 100%;
content: attr(tt);
padding: 5px;
background: #333;
color: #fff;
}
[tt]::before,
[tt]::after {
position: absolute;
/* Middle 3 */
left: 50%;
transform: translate(-50%, 50%);
}
/* First 3 */
[tt]:nth-child(-n+3)::before,
[tt]:nth-child(-n+3)::after {
transform: translate(0 , 50%);
}
/* Last 3 */
[tt]:nth-last-child(-n+3)::before,
[tt]:nth-last-child(-n+3)::after {
transform: translate(-100%, 50%);
}
/* add animation */
[tt]:hover::before,
[tt]:hover::after {
animation: tt-move1 100ms ease-out forwards;
display: block;
}
[tt]:nth-child(-n+3):hover::before,
[tt]:nth-child(-n+3):hover::after {
animation: tt-move2 100ms ease-out forwards;
}
[tt]:nth-last-child(-n+3):hover::before,
[tt]:nth-last-child(-n+3):hover::after {
animation: tt-move3 100ms ease-out forwards;
}
#keyframes tt-move1 {
to {
transform: translate(-50%, 0);
}
}
#keyframes tt-move2 {
to {
transform: translate(0, 0);
}
}
#keyframes tt-move3 {
to {
transform: translate(-100%, 0);
}
}
/*For working demo*/
div {
/*won't work unless set relative, Something that happens in [tt]*/
top:100px;
margin: 10px;
float:left;
width: 20px;
height: 20px;
border: black solid 3px;
}
<div tt="tt1"></div>
<div tt="tt2"></div>
<div tt="tt3"></div>
<div tt="tt4"></div>
<div tt="tt5"></div>
<div tt="tt6"></div>
<div tt="tt7"></div>
<div tt="tt8"></div>
<div tt="tt9"></div>
The above code has a specific animation for each different type of element, something which seems unnecessary. To my knowledge, I am simply applying the same transform to each element (moving the element up along the y-axis) so I expected that the following should also work:
[tt] {
position: relative;
}
[tt]::after {
bottom: 100%;
content: attr(tt);
padding: 5px;
background: #333;
color: #fff;
}
[tt]::before,
[tt]::after {
position: absolute;
/* Middle 3 */
left: 50%;
transform: translate(-50%, 50%);
}
/* First 3 */
[tt]:nth-child(-n+3)::before,
[tt]:nth-child(-n+3)::after {
transform: translate(0 , 50%);
}
/* Last 3 */
[tt]:nth-last-child(-n+3)::before,
[tt]:nth-last-child(-n+3)::after {
transform: translate(-100%, 50%);
}
/*****************Changed code*******************/
/* add animation */
[tt]:hover::before,
[tt]:hover::after {
animation: tt-move 100ms ease-out forwards;
display: block;
}
#keyframes tt-move {
to {
transform: translateY(0);
}
}
/*///////////////Changed code/////////////////*/
/*For working demo*/
div {
/*won't work unless set relative, Something that happens in [tt]*/
top:100px;
margin: 10px;
float:left;
width: 20px;
height: 20px;
border: black solid 3px;
}
<div tt="tt1"></div>
<div tt="tt2"></div>
<div tt="tt3"></div>
<div tt="tt4"></div>
<div tt="tt5"></div>
<div tt="tt6"></div>
<div tt="tt7"></div>
<div tt="tt8"></div>
<div tt="tt9"></div>
After some research, I now understand that transform: translateY(Δy); is the same as saying transform: translate(0,Δy); which is causing the unexpected result. Unfortunately that was the only method I have been able to find that looks like it is supposed to do what I wanted.
I am looking for a method to transform:translate that allows the x-axis of a previous transform:translate to stay the same, while only changing the y-axis.
Is there a different way to accomplish this simplification? Or am I stuck using the repetitious code from above?

When you animate transform you have to add any already set values or else they will temporary be overwritten.
In this case you could animate the bottom instead, which will give the output you want.
[tt] {
position: relative;
}
[tt]::after {
bottom: 100%;
content: attr(tt);
padding: 5px;
background: #333;
color: #fff;
}
[tt]::before,
[tt]::after {
position: absolute;
/* Middle 3 */
left: 50%;
transform: translate(-50%, 50%);
}
/* First 3 */
[tt]:nth-child(-n+3)::before,
[tt]:nth-child(-n+3)::after {
transform: translate(0 , 50%);
}
/* Last 3 */
[tt]:nth-last-child(-n+3)::before,
[tt]:nth-last-child(-n+3)::after {
transform: translate(-100%, 50%);
}
/*****************Changed code*******************/
/* add animation */
[tt]:hover::before,
[tt]:hover::after {
animation: tt-move 100ms ease-out forwards;
}
#keyframes tt-move {
to {
bottom: 170%;
}
}
/*///////////////Changed code/////////////////*/
/*For working demo*/
div {
/*won't work unless set relative, Something that happens in [tt]*/
top:100px;
margin: 10px;
float:left;
width: 20px;
height: 20px;
border: black solid 3px;
}
<div tt="tt1"></div>
<div tt="tt2"></div>
<div tt="tt3"></div>
<div tt="tt4"></div>
<div tt="tt5"></div>
<div tt="tt6"></div>
<div tt="tt7"></div>
<div tt="tt8"></div>
<div tt="tt9"></div>

Related

CSS animations out of sync by 1 frame

I have two animations called slide and bounce-return which both should be playing with 0 delay and 1s duration. Due to what I suspect is some kind of race condition in animation processing logic, these animations are out of sync by 1 frame regardless of animation speed or refresh rate. How can I stop these circles from jumping in and out?
(If you don't see any problem right away, view the snippet in full page or open the developer tools.)
.items {
--var-circle-size: 16px;
--var-circle-space: 8px;
--var-circle-border: solid red;
--var-circle-border-width: 0px;
--var-circle-shadow: 3px 2px 4px -1px rgba(0, 0, 0, 0.4);
--var-circle-shadow-high: 6px 4px 6px -2px rgba(0, 0, 0, 0.2);
--var-circle-count: 5;
--var-anim-bounce-func: cubic-bezier(0.7, 0.1, 0.6, 1.6);
--var-anim-time-unit: calc(1s);
--var-anim-color-cycle-time: calc(var(--var-circle-count)*var(--var-anim-time-unit));
--var-anim-color-cycle-func: steps(1);
--var-anim-color-1: #6db;
--var-anim-color-2: #be4;
--var-anim-color-3: #ec5;
--var-anim-color-4: #d86;
--var-anim-color-5: #f8c;
--var-anim-slide-time: var(--var-anim-time-unit);
--var-anim-slide-func: linear;
--var-circle-size-space: calc(var(--var-circle-size) + var(--var-circle-space));
--var-anim-slide-amount: calc(var(--var-circle-size-space)/2);
--var-anim-slide-start: calc(-1*var(--var-anim-slide-amount));
--var-anim-slide-end: var(--var-anim-slide-amount);
}
.maximized {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.items {
font-size: 0;
white-space: nowrap;
user-select: none;
pointer-events: none;
margin-right: calc(-1*var(--var-circle-space) - var(--var-circle-size-space));
animation: slide var(--var-anim-slide-time) var(--var-anim-slide-func) infinite;
}
.circle {
width: var(--var-circle-size);
height: var(--var-circle-size);
border-radius: 100%;
box-shadow: var(--var-circle-shadow);
display: inline-block;
margin: 0;
margin-right: var(--var-circle-space);
box-sizing: border-box;
border: var(--var-circle-border);
border-width: min(var(--var-circle-border-width), calc(var(--var-circle-size)/2));
background-color: var(--var-anim-bgcolor);
--var-color-cycle-anim: anim-color-cycle var(--var-anim-color-cycle-time) var(--var-anim-color-cycle-func) calc(var(--var-anim-delay-fact)*var(--var-anim-time-unit)) infinite;
animation: var(--var-color-cycle-anim);
}
#keyframes anim-color-cycle {
0% {
--var-anim-bgcolor: var(--var-anim-color-1);
}
20% {
--var-anim-bgcolor: var(--var-anim-color-2);
}
40% {
--var-anim-bgcolor: var(--var-anim-color-3);
}
60% {
--var-anim-bgcolor: var(--var-anim-color-4);
}
80% {
--var-anim-bgcolor: var(--var-anim-color-5);
}
100% {
--var-anim-bgcolor: var(--var-anim-color-1);
}
}
#keyframes slide {
0% {
transform: translate(var(--var-anim-slide-start), 0);
}
100% {
transform: translate(var(--var-anim-slide-end), 0);
}
}
#keyframes bounce-inout {
40%,
60% {
transform: translate(0, var(--var-anim-bounce-inout-fact));
box-shadow: var(--var-circle-shadow-high);
}
}
#keyframes bounce-return {
10% {
left: 0;
}
90%,
100% {
left: var(--var-anim-bounce-return-amount);
}
}
#keyframes bounce-inout-fact-alternate {
0% {
--var-anim-bounce-inout-fact: calc(-1*var(--var-circle-size-space));
}
50% {
--var-anim-bounce-inout-fact: var(--var-circle-size-space);
}
}
.circle:nth-child(1) {
--var-anim-delay-fact: -4;
}
.circle:nth-child(2) {
--var-anim-delay-fact: -3;
}
.circle:nth-child(3) {
--var-anim-delay-fact: -2;
}
.circle:nth-child(4) {
--var-anim-delay-fact: -1;
}
.circle:nth-child(5) {
--var-anim-delay-fact: -0;
}
.circle:last-child {
--var-anim-bounce-inout-fact: calc(-1*var(--var-circle-size-space));
--var-anim-bounce-return-amount: calc(-1 * var(--var-circle-count) * var(--var-circle-size-space));
position: relative;
animation: var(--var-color-cycle-anim), bounce-inout var(--var-anim-time-unit) var(--var-anim-bounce-func) infinite, bounce-return var(--var-anim-time-unit) ease-in-out infinite, bounce-inout-fact-alternate calc(2*var(--var-anim-time-unit)) steps(1) infinite;
}
<div class="maximized container">
<div class="items">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
</div>
I have a theory that combining everything into one set of keyframes for each circle, rather than try to synchronise an animation on items with the circle animations, might help remove the problem with phasing.
To test it here's a snippet that roughly reproduces the action of the given code. In it the items div is not animated. Each circle keeps its original color and is animated to the right, up, back, to the right, down, back - with little bounces at each end.
No 'flashing/shadowing' has been observed. Also the amount of processing being done is less.
On the code in the question my laptop was showing an average of around 5% cpu and 15% gpu usage. On this snippet they are around 1.5% and 11.5% respectively.
.items {
--size: 16px;
--space: 8px;
--border: solid red;
--border-width: 0px;
--shadow: 3px 2px 4px -1px rgba(0, 0, 0, 0.4);
--shadow-high: 6px 4px 6px -2px rgba(0, 0, 0, 0.2);
--count: 5;
--bounce-func: cubic-bezier(0.7, 0.1, 0.6, 1.6);
--time-unit: calc(1s);
--cycle-time: calc(2 * var(--count)*var(--time-unit));
--color-cycle-func: steps(1);
--color-1: #6db;
--color-2: #be4;
--color-3: #ec5;
--color-4: #d86;
--color-5: #f8c;
--slide-time: var(--time-unit);
--slide-func: linear;
}
.maximized {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.items {
font-size: 0;
white-space: nowrap;
user-select: none;
pointer-events: none;
width: calc((var(--size) + var(--space)) * var(--count));
height: var(--size);
position: relative;
}
.circle {
position: absolute;
width: var(--size);
height: var(--size);
border-radius: 100%;
box-shadow: var(--shadow);
display: inline-block;
margin: 0;
margin-right: var(--space);
box-sizing: border-box;
border: var(--border);
border-width: min(var(--border-width), calc(var(--size)/2));
animation: bounceround infinite var(--cycle-time) var(--slide-func);
animation-delay: var(--delay);
background-color: var(--color);
}
.circle:nth-child(1) {
--color: var(--color-1);
--delay: -8s;
}
.circle:nth-child(2) {
--color: var(--color-2);
--delay: -6s;
}
.circle:nth-child(3) {
--color: var(--color-3);
--delay: -4s;
}
.circle:nth-child(4) {
--color: var(--color-4);
--delay: -2s;
}
.circle:nth-child(5) {
--color: var(--color-5);
--delay: 0s;
}
#keyframes bounceround {
0% {
}
36.6666% {
transform: translateX(calc(var(--count) * 100%)); /* move to the right */
}
40% {
transform: translateX(calc((var(--count) - 0.5) * 100%)) translateY(calc(-100% - var(--size))); /* go up a bit */
}
41% {
transform: translateX(calc((var(--count) - 1) * 100%)) translateY(calc(-100% - (var(--size) / 2))); /* come down a fraction */
}
45% {
transform: translateX(0) translateY(-100%); /* move to the left */
}
49% {
transform: translateX(0) translateY(calc(var(--size) / 4)); /* jump down a bit*/
}
50% {
transform: translateX(0) translateY(0); /* go down to start position */
}
86.6666% {
transform: translateX(calc(var(--count) * 100%)); /* move to the right */
}
90% {
transform: translateX(calc((var(--count) - 0.5) * 100%)) translateY(calc(100% + var(--size))); /* go down a bit */
}
91% {
transform: translateX(calc((var(--count) - 1) * 100%)) translateY(calc(100% + calc(var(--size) / 2))); /* go up a fraction */
}
95% {
transform: translateX(0) translateY(100%); /* move to the left */
}
99% {
transform: translateX(0) translateY(calc(-1 * var(--size) / 4)); /* jump up a bit */
}
100% {
transform: translateX(0) translateY(0); /* back to where we started */
}
}
<div class="maximized container">
<div class="items">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
</div>
Possible workaround: Add duplicate version of circles just with color-cycle and no moving animation and have them overlap with original one, and swap visibility of it for just a few millis when the animation iteration is about to restart.

CSS Animation - drawing line from left to right on mouseenter, then disappearing left to right on mouseleave

I'm trying to animate a line that underlines from left to right on 'mouseenter' and then to disappear from left to right on 'mouseleave' instead of the current behaviour where it disappears right to left.
Example of what I'm trying to achieve (but with animations not transitions):
https://jsfiddle.net/1gyksyoa/
I have tried to reverse the 'draw' animation but this doesn't achieve what I'm trying to accomplish.
#keyframes draw-reverse {
100% {
width: 0;
background-color: red;
}
0% {
width: 47px;
background-color: red;
}
}
I have put together this to give a better understanding of the problem;
https://jsfiddle.net/Lq560be9/
Currently, I have the line animating from left to right as desired on 'mouseenter', but on 'mouseleave' it disappears from right to left, whereas I am trying to get the line to also disappear from left to right.
But the problem isn't animation's ability it's the properties that you're animating. Instead of animating the width of an object you should animate its "X" position using translate. (this is much more performant too)
Simply put you need to MOVE the bar from left to center to right instead of trying to scale it.
(there's lots of code here to show the different states the only one you really need to follow is .ex4)
document.querySelector('#animate').addEventListener('mouseenter', function(){
this.classList.toggle('over');
})
document.querySelector('#animate').addEventListener('mouseleave',function(){
this.classList.toggle('out');
})
.example {
margin: 30px auto;
padding: 10px;
background: #dadada;
max-width: 50%;
position: relative;
}
.example:after {
content:'';
position: absolute;
width: 50%;
height: 5px;
background-color: #333;
left:0;
bottom:0;
}
.ex1:after {
transform: translateX(-100%);
}
.ex3:after {
transform: translateX(200%);
}
.ex4 {
overflow: hidden;
}
.ex4:after {
transform: translateX(-100%);
}
.ex4.over:after {
animation: animate-in 1s ease-in-out 1 normal forwards;
}
.ex4.out:after {
animation: animate-out 1s ease-in-out 1 normal forwards;
}
#keyframes animate-in {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0);
}
}
#keyframes animate-out {
0% {
transform: translateX(0);
}
100% {
transform: translateX(200%);
}
}
<div class="example ex1">Object State 1</div>
<div class="example ex2">Object State 2</div>
<div class="example ex3">Object State 3</div>
<div id="animate" class="example ex4">Full example (hover)</div>
As a follow on from above, an alternative solution without using the translate property.
The new animation for mouseleave is;
#keyframes draw-reverse {
0% {
width: 47px;
}
25% {
width: calc(100% - 16px);
}
26% {
width: auto;
right: 8px;
left: 8px;
}
100% {
width: auto;
right: 8px;
left: calc(100% - 8px);
}
}
Full solution can be seen here - https://jsfiddle.net/1wq25tg7/

css transition for page transitioin not triggering

I have a page transition I'm trying to work into my site. I have 2 50% height, 100% width elements, one placed before and after the body (with pseudo-selectors). I would like the 2 elements to slide to the middle of the screen, covering the background content. The transition is triggered when the "is-changing" class is added to the body, via Javascript.
document.getElementById("btn").addEventListener("click", fakeReq);
function fakeReq() {
let body = document.body;
body.classList.add("is-changing");
console.log("class added");
setTimeout(function() {
body.classList.remove("is-changing");
console.log("class removed");
}, 5000);
}
body {
height: 100vh;
width: 100%;
background-color: grey;
}
main {
display: flex;
height: 100%;
justify-content: center;
align-items: center;
}
body::after, body::before {
height: 50vh;
width: 100%;
position: fixed;
left: 0;
background-color: blue;
z-index: 10;
}
body::before {
top: 0;
transform: translateY(-100%);
}
body::after {
bottom: 0;
transform: translateY(100%);
}
body.is-changing::after, body.is-changing::before {
transform: translateY(0);
}
.loading-bar {
position: fixed;
height: 2px;
width: 90%;
}
.loading-bar::before {
position: absolute;
background-color: aqua;
left: 0;
top: 0;
height: 100%;
width: 100%;
transform: scaleX(0);
transform-origin: left center;
}
.is-changing .loading-bar::before {
transform: scaleX(1);
}
<body>
<main>
<div class="index main-content">
<h1>Home Page</h1>
<button id="btn">html request</button>
</div>
</main>
</body>
It looks to me like you're running into two issues.
The first issue is that you forgot to include the content attribute in your pseudo elements (often this will be empty, like content: ""). Without this attribute, your pseudo elements will not exist in the DOM. Running your code snippet and inspecting it confirms this, since the pseudo elements are nowhere to be found.
Second, you're creating multiple pseudo elements. body::before is it's own pseudo element, and body.is-changing::before is a separate pseudo element. If you are hoping to create a constant set of elements that act as "doors" for a loading display, you may want to consider creating two real elements that sit in position: fixed above and below the viewport, and then slide in or out when a class is added. Perhaps these could be div.upper-door and div.lower-door.
Also, it looks to me like you're in need of a transition for your transform, or else the pseudo elements will just "snap" back and forth. You can take control of the position of your elements at different points during this transition by using a css animation. Your JavaScript would largely remain the same, except for targeting the .upper-door and .lower-door divs using document.querySelector(), or simply using IDs rather than classes and targeting with getElementById(), if that makes more sense for you. Your css might look like this:
div.upper-door {
top: 0;
transform: translateY(-100%);
}
div.upper-door.is-changing {
animation-duration: 5s;
animation-name: upper-door-closeopen;
}
div.lower-door {
bottom: 0;
transform: translateY(100%);
}
div.lower-door.is-changing {
animation-duration: 5s;
animation-name: lower-door-closeopen;
}
#keyframes upper-door-closeopen {
0% {
transform: translateY(-100%);
}
25% {
transform: translateY(0);
}
75% {
transform: translateY(0);
}
100% {
transform: translateY(-100%);
}
}
#keyframes lower-door-closeopen {
0% {
transform: translateY(100%);
}
25% {
transform: translateY(0);
}
75% {
transform: translateY(0);
}
100% {
transform: translateY(100%);
}
}
The css animation will be triggered when .is-changing is added to the element. As you experiment, you may find different permutations of this solution (such as using event listeners if a button click is triggering the loading screen) to be ideal.
There is a great resource on MDN for css animations if you would like more information.
You missed to add the content property on the pseudo-elements which is mandatory to make them available on the page. You also missed to add the transition property on the pseudo-elements to achieve your animation of sliding up/down.
Here's a snippet containing a working demo, I only used the code that is related to your issue:
document.getElementById("btn").addEventListener("click", fakeReq);
function fakeReq() {
let body = document.body;
body.classList.add("is-changing");
console.log("class added");
setTimeout(function() {
body.classList.remove("is-changing");
console.log("class removed");
}, 5000);
}
body {
height: 100vh;
width: 100%;
background-color: grey;
position: relative; /* not really related to your issue but, to make sure that the body's pseudo-elements are positioned relative to the body */
}
main {
display: flex;
height: 100%;
justify-content: center;
align-items: center;
}
body::after, body::before {
content: ""; /* make the pseudo-elements available */
height: 50vh;
width: 100%;
position: fixed;
left: 0;
background-color: blue;
z-index: 10;
transition: all .8s ease-out; /* allow the animation, change this rule per your requirements */
}
body::before {
top: 0;
transform: translateY(-100%);
}
body::after {
bottom: 0;
transform: translateY(100%);
}
body.is-changing::after, body.is-changing::before {
transform: translateY(0);
}
<body>
<main>
<div class="index main-content">
<h1>Home Page</h1>
<button id="btn">html request</button>
</div>
</main>
</body>
Learn more about after pseudo-element.
Learn more about before pseudo-element.
You can use the following
document.getElementById("btn").addEventListener("click", fakeReq);
function fakeReq() {
let body = document.body;
body.classList.add("is-changing");
console.log("class added");
setTimeout(function() {
body.classList.remove("is-changing");
console.log("class removed");
}, 5000);
}
body {
height: 100vh;
width: 100%;
background-color: grey;
}
main {
display: flex;
height: 100%;
justify-content: center;
align-items: center;
}
body::after, body::before {
content:'';
height: 50vh;
width: 100%;
position: fixed;
left: 0;
background-color: blue;
z-index: 10;
}
body::before {
content:'';
top: 0;
transform: translateY(-100%);
transition: .5s all;
}
body::after {
content:'';
bottom: 0;
transform: translateY(100%);
}
body.is-changing::after, body.is-changing::before {
content:'';
transform: translateY(0);
}
.loading-bar {
position: fixed;
height: 2px;
width: 90%;
}
.loading-bar::before {
content:'';
position: absolute;
background-color: aqua;
left: 0;
top: 0;
height: 100%;
width: 100%;
transform: scaleX(0);
transform-origin: left center;
}
.is-changing,.loading-bar::before {
transform: scaleX(1);
}
<body>
<main>
<div class="index main-content">
<h1>Home Page</h1>
<button id="btn">html request</button>
</div>
</main>
</body>

Making pure css image slider responsive

The following pure css slider is working well, but I need to make it responsive. I've tried replacing the pixel-based sizes with percentages and with vw, but it doesn't line up. I'd be grateful for any ideas.
Here's the html:
<section class="slideshow">
<div class="slideshow-container slide">
<img src="images/anim/home-animation1.jpg" alt="pills">
<img src="images/anim/home-animation2.jpg" alt="scientist">
<img src="images/anim/home-animation3.jpg" alt="chemical structure">
<img src="images/anim/proudmembermassbio.jpg" alt="proud member of MassBio"> </div>
</section>
And the css:
/*general styles*/
html { box-sizing: border-box; }
*, *:before, *:after { box-sizing: inherit; }
/* SLIDESHOW STYLES */
.slideshow-container {
width: 1400px; /* the entire "stage" */
font-size: 0;
transition: 1s ease;
height: 315px;
}
.slideshow-container:hover { animation-play-state: paused; }
.slideshow { /* the visible "stage" */
width: 350px;
margin: 1rem auto -1rem;
overflow: hidden;
border: solid 1px white;
}
img, .text-container {
width: 350px;
height: auto;
display: inline-block;
font-size: 16px;
text-align: center;
}
.text-container { /* for text slides */
height: 195px;
position: relative;
}
.slide { animation: slide 10s ease infinite; }
#keyframes slide {
0% { transform: translateX(0%); }
12.5% { transform: translateX(0%); }
25% { transform: translateX(-25%); }
37.5% { transform: translateX(-25%); }
50% { transform: translateX(-50%); }
62.5% { transform: translateX(-50%); }
75% { transform: translateX(-75%); }
87.5% { transform: translateX(-75%); }
99% { transform: translateX(-75%); }
100% { transform: translateX(0); }
}
.p {
margin-top: 140px;
text-align: center;
}
Maybe this is too late for the user that posted this question, but can be helpful for someone else that want a pure responsive CSS slider.
I have created a working example in this CodePen that is working as requested using percentages for widths and in the animation, and for this reason it is responsive and works really well in each resolutions.
All the main solution to have the responsiveness is here:
slider__container {
display: flex;
position: relative;
animation: 30s slide infinite;
font-size: 0;
width: 1000%; /* because I am using 10 slides */
}
The width should be calculated accordingly to how many slides are there in the slider: slides x 100% (slides times 100%, in my example 1000%).

Make a line move from (0,0) to any angle

I've created a line, which appears from 0 to full length on mouse hover. In this code, the line moves from left to right. I just want to make it move from (0,0) to any given angle. Is there any way I can achieve this?
.cspaceintro .intro-container .line2 {
position: relative;
left: 890px;
bottom: 25px;
width: 2%;
height: 30px;
background-color: #3ebbff;
background: -webkit-gradient(linear, 0 0, 0 100%,from(#7BC3FF), to(#7BC3FF));
-webkit-animation: aaa 2s linear 1;
-webkit-animation-fill-mode: both;
}
#keyframes aaa {
0% {
width: 0%;
}
30% {
width: 2%;
}
60% {
width: 4%;
}
100% {
width: 5%;
}
}
<div class="cspaceintro">
<div class="intro-container">
<div id="li2"></div>
</div>
</div>
You can use CSS3 properties transform and transform-origin.
.cspaceintro {
/* rotate to the respective degrees */
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
/* sets the origin point for the transformed element */
-webkit-transform-origin: 0;
transform-origin: 0;
}
Please refer the link: https://developer.mozilla.org/en/docs/Web/CSS/transform?v=example#Live_example

Resources