I'm currently doing a React app which shows what music I'm listening at that time. Obviously some of song names, album name etc. are longer than others so I want to show overflowing part with animation. I managed to do this and it's kinda okay. Longer text scrolls nicely but my problem is it also animates short texts and that causes some shaking on them during the animation.
Any ideas how to remove that shaking? Also Javascript based solutions are appreciated but this seemed to be shorter solution.
div {
width: 100px;
border: 1px solid black;
}
div p {
overflow: hidden;
white-space: nowrap;
display: inline-block;
position: relative;
min-width: 100%;
animation: 5s linear 0s infinite alternate scrolltext;
}
#keyframes scrolltext {
0%,
25% {
transform: translateX(0%);
left: 0%;
}
75%,
100% {
transform: translateX(-100%);
left: 100%;
}
}
<div>
<p>This is a very long text and rolls nicely</p>
<p>And these</p>
<p>two shaking?!</p>
</div>
use margin-left and margin-right instead of left and right
div {
width: 100px;
border: 1px solid black;
}
div p {
overflow: hidden;
white-space: nowrap;
display: inline-block;
position: relative;
min-width: 100%;
animation: 5s linear 0s infinite alternate scrolltext;
}
#keyframes scrolltext {
0%,
25% {
transform: translateX(0%);
margin-left: 0%;
}
75%,
100% {
transform: translateX(-100%);
margin-left: 100%;
}
}
<div>
<p>This is a very long text and rolls nicely</p>
<p>And these</p>
<p>two shaking?!</p>
</div>
Related
I'm creating a portfolio site that has a filterable infinite wall gallery underneath a hero image that slides off to the right when you click (and slides back on screen with another click). I'm having trouble though, getting this sliding image to work correctly. The photo gallery will be a headache for another day.
There will be a small right arrow button on the left side. To make this slider more obvious I'd like to animate a slight right-left bounce of the image when you hover over this image, then when you click the arrow (or would probably be better to click anywhere on the pic) it slides off screen to the right, revealing this photo gallery underneath. Then you can slide this image back over the gallery with another arrow button on the right.
I found a solution that's most of the way there, using a label input checkbox with a transition property to get it to show as default and animate off screen with the arrow click, but it slides down, not right. It's a little wonky, and I feel like it could be simplified to some degree.
I also tried changing the input from a checkbox to a button and doing animation keyframes, but the animation only played on refresh, and disappears/reappears instantly with no animation with a button click. I may have just targeted the wrong element though.
This is a very rough ideas as to what I'm going for, just thrown together in XD. Final design will be much more pleasant. I forgot the arrow on the second screen, but there'd be one on the right side of the screen to slide that hero image back over the gallery.
If this could be done in just HTML and CSS that'd be great, but if I need to use js or jQuery to do this properly then that's fine.
This is what I have currently that needs some serious work:
<section>
<div class="pv-wrapper">
<h1>PHOTO + VIDEO</h1>
<div class="btn-container">
<ul>
<li class="automotive">Automotive</li>
<li class="video">Video</li>
<li class="portraits">Portraits</li>
<li class="landscapes">Landscapes</li>
</ul>
</div>
<label class="slider">
<img class="arrow" src="images/right-arrow.png">
<input type="checkbox" name="">
<div class="photo-slider"></div>
</label>
</div>
</section>
.pv-wrapper {
width: 100%;
height: 750px;
position: relative;
border-left: 100px solid orange;
color: rgba(0, 0, 0, 0.5);
font-size: small;
display: inline-block;
}
.pv-wrapper h1 {
font-size: 50px;
color: white;
text-transform: uppercase;
letter-spacing: 3px;
position: absolute;
bottom: 225px;
left: -40px;
margin-left: -30px;
-webkit-transform: rotate(270deg);
-moz-transform: rotate(270deg);
-ms-transform: rotate(270deg);
-o-transform: rotate(270deg);
transform: rotate(270deg);
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-o-transform-origin: 0 0;
transform-origin: 0 0;
}
.btn-container ul {
display: inline-block;
padding: 50px 0 0 50px;
font-family: 'Poppins-Light';
font-size: 40px;
line-height: 120%;
}
.btn-container ul li a {
text-decoration: none;
color: black;
}
.btn-container ul li a:hover {
color: #68C8E5;
transition: 0.4s ease;
}
.slider {
margin-left: -20px;
}
.arrow {
width: 20px;
margin-top: 90px;
}
.slider > input {
display: none;
}
.slider > input:not(:checked) ~ .photo-slider {
top: 100px !important;
}
.photo-slider {
position: fixed;
height: 750px;
width: 100%;
top: 100%;
left: 100px;
background: url(../images/rs3-bg.jpg);
background-size: cover;
background-position: 75% 50%;
transition: 0.6s;
}
[1]: https://i.stack.imgur.com/nob93.jpg
Got it to work thanks to #MonsterBasket! Had to make a couple slight changes but this is what worked, including the bounce on hover:
.slider {
margin-left: -20px;
cursor: pointer;
display: inline-block;
}
.photo-slider {
position: fixed;
animation-duration: 1s;
animation-fill-mode: both;
animation-timing-function: ease-in-out;
animation-iteration-count: 1;
animation-delay: 0.5s;
}
.photo-slider:hover {
animation-name: bounce;
}
#keyframes bounce {
0%, 100%, 20%, 50%, 80% {
transform: translateX(0)
}
40% {
transform: translateX(30px)
}
60% {
transform: translateX(15px)
}
}
.slider > input {
display: none;
}
.slider > input:not(:checked) ~ .photo-slider {
top: 100px;
}
.slider > input:checked ~ .photo-slider {
left: calc(100% - 60px);
top: 100px;
}
.arrow {
width: 60px;
margin-top: 345px;
}
.slider > input:not(:checked) ~ .photo-slider .arrow {
transform: rotate(-360deg);
transition: 1s;
}
.slider > input:checked ~ .photo-slider .arrow {
transform: rotate(-180deg);
transition: 1s;
}
.photo-slider {
position: fixed;
height: 750px;
width: 100%;
top: 100%;
left: 100px;
background: url(../images/rs3-bg.jpg);
background-size: cover;
background-position: 75% 50%;
transition: 0.6s;
}
The reason you need a checkbox rather than a button is because pure CSS doesn't record state. So even though you can make a button play an animation on click, you can't set it as "clicked" so that you can then "unclick" it.
In .slider > input:not(:checked) ~ . photo-slider you're saying "when this is not clicked, be 100px from the top. .photo-slider is less specific, so there you're saying "when the above rule doesn't apply, be 100% from the top (off the bottom of the screen". All the other attributes aren't specified in the above rule, so they'll always be applied.
To make it slide off to the right, you just need to play with where and how you list those properties. I don't know exactly how you want to position it within the rest of your page, but I think this should get you most of the way there:
.slider > input:not(:checked) ~ .photo-slider {
left: 0px; /* This will put it hard left when unchecked, you also don't need !important, as this rule is more specific than the one below.*/
}
.photo-slider {
position: fixed;
height: 750px;
width: 100%;
top: 100px;
left: calc(100% - 20px); /* this will leave 20px sticking out from the right side of the screen */
background: url(../images/rs3-bg.jpg);
background-size: cover;
background-position: 75% 50%;
transition: 0.6s;
}
You can probably also change this:
<label class="slider">
<img class="arrow" src="images/right-arrow.png">
<input type="checkbox" name="">
<div class="photo-slider"></div>
</label>
To this:
<label class="slider">
<input type="checkbox" name="">
<div class="photo-slider">
<img class="arrow" src="images/right-arrow.png">
</div>
</label>
Which will keep the arrow on top of your hero image. You'll have to figure out the CSS to position it yourself, but then you could do this to change the direction of the arrow:
.slider > input:not(:checked) ~ .photo-slider .arrow {
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
}
As for making it bounce on hover, this explains perfectly. Your CSS rule would be .photo-slider:hover.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a red box as the element to animate.
Here is a simple representation of how I want to animate the red box.
Here is a try but as you see the anchor point of the movement is at the left of the box no the center as I wish to be:
.yo-yo {
display: block;
position: absolute;
height: 50px;
width: 200px;
background: red;
transform-origin: 50% 50%;
animation: yo-yo 0.5s infinite alternate; /* Animation speed and type */
}
/* Animation beginning and ending */
#keyframes yo-yo {
from { left: 0 }
to { left: 20px }
}
<span class="yo-yo"></span>
Here is the script tag of that specific version of TweenMax:
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js" integrity="sha512-DkPsH9LzNzZaZjCszwKrooKwgjArJDiEjA5tTgr3YX4E6TYv93ICS8T41yFHJnnSmGpnf0Mvb5NhScYbwvhn2w==" crossorigin="anonymous"></script>
Your making it too complicated. Just use the percentages in #keyframes, and use transform: translateX(number) like so:
#keyframes yo-yo {
0% {transform: translateX(0); }
25% { transform: translateX(-20px); }
75% { transform: translateX(20px); }
100% { transform: translateX(0px); }
}
You should try to use transform instead of giving positions. For a better understanding, checkout this link CSS translation vs changing absolute positioning values.
You need to use the progress instead of just simply declaring a from and to in the keyframes rule
Something like this would suffice. If you want a repeating animation then just add a infinite before linear
html,
body {
padding: 0;
margin: 0;
outline: none;
border: 0;
}
.yo-yo {
display: block;
position: absolute;
height: 50px;
width: 200px;
background: red;
transform-origin: 50% 50%;
animation: yo-yo 2s linear;
/* Animation speed and type */
animation-timing-function: ease-in-out;
}
/* Animation beginning and ending */
#keyframes yo-yo {
0% {
left: 0px;
}
25% {
left: -100px;
}
50% {
left: 0px;
}
75% {
left: 100px;
}
100% {
left: 0px;
}
}
<span class="yo-yo"></span>
You can use animation with infinite normal linear. If you remove infinite from animation then it will stop after one iteration. Your animation is divided into 5 parts. 0, all the way right, 0, all the way left, 0. So start changing the left position from 0%, 25%, 50%, 75% and 100%.
.yoyo-container{
background-color: #DEEBF7;
padding:12px;
position: relative;
width: 200px;
height: 16px;
margin: 0 auto;
}
.yo-yo {
display: block;
position: absolute;
height: 16px;
width: 200px;
background: red;
transform-origin: 50% 50%;
animation: yo-yo 2s infinite normal linear; /* Animation speed and type */
}
/* Animation beginning and ending */
#keyframes yo-yo {
0% {transform: translateX(0); }
25% { transform: translateX(50%); }
50% { transform: translateX(0); }
75% { transform: translateX(-50%); }
100% { transform: translateX(0); }
}
<div class="yoyo-container">
<span class="yo-yo"></span>
</div>
I want to make sure that the div container holds the text inside it without leaking any text outside. How can I make it responsive to grow or shrink the container size depending upon the dynamic text?
.element {
display: inline-block;
text-indent: 15px;
background-color: #0074d9;
width: 120px;
margin-right: 5px;
/* left and right margin of flex elements inside this element container */
margin-left: 5px;
animation: roll 3s infinite;
transform: rotate(30deg);
opacity: .5;
}
#keyframes roll {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
<div class="element">
<p>Welcome!</p>
<p>${user_name}</p>
<p>${user_email}</p>
<p>${user_contact} </p>
</div>
faize
check this https://jsfiddle.net/kdrbh1Lw/10/
add this css rules to element class.
flex-wrap: wrap
height: auto
width: max-content
when dynamically adding new data element container should expand both vertically and horizontally.
.element {
flex-wrap: wrap;
text-indent: 15px;
background-color: #0074d9;
height: auto;
width: max-content;
margin-right: 5px;
margin-left: 5px;
animation: roll 3s infinite;
transform: rotate(30deg);
opacity: .5;
}
#keyframes roll {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="element">
<p>welcome</p>
<p>${user_name}</p>
<p>${user_email}</p>
<p>${user_contact}</p>
<p>${new_data}</p>
<p>long long long long long long text</p>
</div>
</body>
</html>
As mentioned in the comments, your problem here is that the text is wrapping because you gave its parent container a set width of 120px. If you A) ditch the width or B) give it a min-width of 120px, you will get it to resize to accommodate longer names.
.element {
display: inline-block;
background-color: #0074d9;
min-width: 120px;
margin-right: 5px;
margin-left: 5px;
padding: 0 10px;
animation: roll 3s infinite;
transform: rotate(30deg);
opacity: .5;
}
#keyframes roll {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
<div class="element">
<p>Welcome!</p>
<p>Someguy Longlastname</p>
<p>${user_email}</p>
<p>${user_contact} </p>
</div>
How about the following. Using min-width you can specify a width it should definitely have but it can grow as much as it wants. If you don't like that you could also set a max-width.
.element {
display: inline-block;
padding: 15px; /* gives equal spacing around */
background-color: #0074d9;
min-width: 120px;
margin-right: 5px;
/* left and right margin of flex elements inside this element container */
margin-left: 5px;
animation: roll 3s infinite;
transform: rotate(30deg);
opacity: .5;
}
.element p {
margin: 0 0 10px 0;
}
.element p:last-of-type {
margin: 0;
}
#keyframes roll {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
<div class="element">
<p>Welcome!</p>
<p>${user_name}</p>
<p>${user_email}</p>
<p>${user_contact} </p>
<p>rory mcCrossan</p>
</div>
I have a problem with css and I have to admit that I am just learning it.
I have a header that stays at the top and a "content" area that should be scrollable.
Here are the two css classes:
body,
div {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
width: 100%;
height: 100%;
}
#header {
overflow: auto;
position: absolute;
width: 100%;
height: 200px;
background-color: #DEE7F2;
border-width: 2px;
border-bottom-width:2px;
border-bottom-color:Black;
border-bottom-style: solid;
}
#main {
overflow: auto;
position: absolute;
top: 200px;
width: 100%;
bottom: 0;
}
<body>
<div id="header">
some stuff here
</div>
<div id="main">
a lot of stuff here
</div>
<body>
This works fine though. Now I added a drop down to select the scale of the "content area" because the content will be quite large.
This is the CSS class that I add to the main div to have the scale of 10%:
.scale10 {
-ms-transform: scale(0.1);
-moz-transform: scale(0.1);
-o-transform: scale(0.1);
-webkit-transform: scale(0.1);
transform: scale(0.1);
-ms-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-o-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
This is how the page look like in 100% scale (without the additional class)
As you can see the page is scaled but is not using the whole width of the screen. Also, the scrollbars do not use the whole width... I want the main page to use the full width thats why I used the "width: 100%" statement in the main class. I tried to remove the statement but then the scrollbars are missing...
What I want is to scale the main-div but leave the width at 100% so that the image uses the whole screen. Also I want scrollbars because the content will still be larger then the screen - even with a scale of 10%.
Can some CSS god help me please?
This should do your effect:
JSFIDDLE
You simply have to wrap your content in another container, and you place this container in your main area. Then you scale not your main area, but just your content.
body,
html {
height: 100%;
}
#main {
width: 100%;
height: 100%;
background-color: black;
overflow: auto;
}
.content {
width: 500px;
height: 400px;
margin: 0 auto;
background-color: white;
transition: all 1s ease;
-webkit-transition: all 1s ease;
}
.content:hover {
width: 120%;
}
<div id="main">
<div class="content"></div>
</div>
Added a hover state just for demonstration.
Saw this cool 3x3 grid on this site and cant seem to re-create the animation it has.
The image folds a bit on hover and folds completely in half on a click.
Reference: http://doyouimpress.com/
I've tried doing something similar in CSS however the :active psuedo selector won't open the page completely unless you hold click. Would I only be able to re-create this animation w jquery?
Here's what I've done so far (webkit only): http://jsfiddle.net/JDH9/4wrnf/8/
HTML
<div id="container">
<div id="test">
<div id="left"></div>
<div id="center"></div>
</div>
CSS
#container {
position: absolute;
top: 50%;
left: 50%;
margin: -200px 0 0 -100px;
-webkit-perspective: 1000;
}
#test {
position: relative;
}
#test div {
width: 200px;
height: 400px;
}
#left {
background: grey;
z-index: 3;
-webkit-transform-origin: 0% 50%;
-webkit-transition-delay: 1s;
}
#center {
background: grey;
z-index: 1;
}
#left {
position: absolute;
top: 0;
left: 0;
-webkit-transition-duration: 2s;
}
#test:hover #left {
-webkit-transform: rotateY(-45deg);
-webkit-transition-delay: 0s;
}
#test:active #left {
-webkit-transform: rotateY(-180deg);
-webkit-transition-delay: 0s;
}