I've got text that 'appears' slowly thanks to a ::before element and a transition. The box created by the ::before code covers the text and the transition makes the box than move horizontally, creating the illusion that the text behind it is appearing in real time. Here's the code:
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: white;
}
p {
font-size: 90px;
}
.test {
position: relative;
}
.test2::before {
content: '';
background-color: white;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
animation: test;
animation-duration: 0.5s;
animation-fill-mode: forwards;
animation-iteration-count: 1;
transform-origin: right;
}
#keyframes test {
0% {
transform: scaleX(1);
}
100% {
transform: scaleX(0);
}
}
<p class="test test2">
TEST
</p>
Code works perfect, but here's the problem. The background has to be the same colour of the box that moved horizontally. I want to have a picture in the background, but now the box that moves horizontally (and it white) is visible. If I make the box opacity 0 or have no background, then it doesn't cover the text anymore. Any way around this?
Related
I'm trying to have an infinite keyframe animation for text (span) moving horizontally by using the translateX property.
I manage to have the beginning of the infinite animation, however when I reach the end of the animation it "jumps" back to the beginning without it being smooth.
Also when reaching the last span of the animation, I would like that we start to see the beginning of the first span, so that it looks like it's indefinitely scrolling and not have blank space at the end of the animation.
I also tried to create different keyframes for each span, but this method made it very difficult to time the speed.
html, body {
margin: 0;
}
.scroll {
display: flex;
position: relative;
width: 100%;
height: 15%;
min-height: 150px;
margin: auto;
background-color: #252525;
overflow: hidden;
z-index: 1;
}
.m-scroll {
display: flex;
position: absolute;
top: 0;
left: 0;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 100%;
white-space: nowrap;
transform: scale(2);
transition: all 1s ease;
}
.m-scroll > div {
display: flex;
animation: scrollText 10s infinite linear;
}
.m-scroll h1 {
margin: 0;
margin-right: 150px;
font-size: 25px;
color: #ffffff;
transition: all 2s ease;
}
#keyframes scrollText {
from {
transform: translateX(0%);
}
to {
transform: translateX(-50%);
}
}
<div class="scroll">
<div class="m-scroll">
<div>
<h1>
<span>TEXT </span><span>INFINITE </span><span>SCROLL</span>
</h1>
<h1>
<span>TEXT </span><span>INFINITE </span><span>SCROLL</span>
</h1>
<h1>
<span>TEXT </span><span>INFINITE </span><span>SCROLL</span>
</h1>
<h1>
<span>TEXT </span><span>INFINITE </span><span>SCROLL</span>
</h1>
</div>
</div>
</div>
So how could I make it become smooth ?
This behavior happens in full screen, on small device, the problem doesn't seem to appear. If you run the code snippet, please expand it
I have stripped things down to give a basic continuous scroll - with the overall width of the 'sentence' (span) being a minimum 100vw in this snippet.
html,
body {
margin: 0;
}
.scroll {
position: relative;
width: 100vw;
height: 15%;
min-height: 150px;
background-color: #252525;
overflow: hidden;
z-index: 1;
margin: 0;
padding: 0;
}
.m-scroll {
overflow_ hidden;
height: 100%;
white-space: nowrap;
animation: scrollText 10s infinite linear;
margin: 0;
font-size: 0;
display: inline-block;
}
span {
font-size: 50px;
display: inline-block;
min-width: 100vw;
margin: 0;
padding: 0;
color: white;
}
#keyframes scrollText {
from {
transform: translateX(0%);
}
to {
transform: translateX(-50%);
}
}
<div class="scroll">
<div class="m-scroll"><span style="rbackground: cyan;">TEXT INFINITE SCROLL </span><span style="rbackground: magenta;">TEXT INFINITE SCROLL </span><span style="rbackground: yellow;">TEXT INFINITE SCROLL </span><span style="rbackground: gray;">TEXT INFINITE SCROLL </span></div>
</div>
Note: I removed the flexes as I have never been able to make them play nicely with scrolling text. Maybe someone can put me right on that.
I am trying to create a curtain effect on some text. I want the text to be hidden at first and then have an animated reveal from the middle of the text to the outer edges. I want this to work even if there is an odd number of letters. In other words, breaking up the string would not work. If there is only one giant character in the string I want it to reveal from the center of the character to the outer edges of the character. I do not want a curtain effect on the background, since I don't know what I want to have for a background yet. I want it only on the text.
Here is what I have so far:
HTML
<div class="container">
<div class="my-name">The Incredible Houdini</div>
</div>
CSS
body {
margin: 0;
}
.container {
position: relative;
font-size: 3vh;
width: 100%;
height: 100vh;
background: lightblue;
}
.my-name {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-size: 2em;
font-weight: bold;
color: darkblue;
width: 0;
overflow: hidden;
white-space: nowrap;
animation: showName 5s linear 3s forwards;
}
#keyframes showName {
from {
width: 0;
}
to {
width: 15ch;
}
}
The overflow:hidden and the width from 0 to 100 give me what I want in terms of the individual characters gradually being revealed instead of popping in like a typewriter. The problem is that it generates from the left to the right. Is there any way I can start expanding the width from the middle to the outer edges?
Firstly, you would need a keyframe to auto width which you can't do. I'd suggest rethinking your methodology.
I'd go with animating a clip path
body {
margin: 0;
}
.container {
position: relative;
font-size: 25vh;
width: 100%;
height: 100vh;
background: lightblue;
display:flex;
justify-content:center;
align-items:center;
}
.my-name {
font-weight: bold;
color: white;
overflow: hidden;
padding: .25em;
background: rebeccapurple;
clip-path: inset(0 100% 0 100%);
animation: showName 5s linear forwards;
}
#keyframes showName {
0% {
clip-path: inset(0 100% 0 100%);
}
100% {
clip-path: inset(0);
}
}
<div class="container">
<div class="my-name">The Incredible Houdini</div>
</div>
I work with search bar, and i want to make it nice, but for some reason transition animation is not working for me, i try to use few methods but only animation css is help example:
.active {
width: 100%;
outline: none !important;
z-index: 901;
border: 1px solid #30a161 !important;
animation: animateRight .6s ease-in-out;
}
#-webkit-keyframes animateRight {
0% {
width: 100px;
}
100% {
width: 100%;
}
}
But transition method for me it's better, so what i want, i have animation hiding body, animation of closing input for search (opening animation i have) maybe better solution to move to transition.
.search_modal {
position: absolute;
top: -50px;
left: 0;
transition: top 1s ease; // here should be animation
}
JsFiddle
So i want 2 animation, first when added class .search_modal it;s moving to -50 on top and when closing again need animation, and input opening and closing.
You need to put the transition property on the element before you transition and make your transition class more specific. The following snippert should do the trick
header .search_container {
position: relative;
display: flex;
flex: 1;
align-items: center;
margin-right: 1rem;
z-index: 1024;
top: 0;
transition: top 1s ease; //Add it here
}
header .search_container.search_modal {
top: -50px;
left: 0;
}
Is it possible to have a body background image aligned to the edge of a container element?
Using boostrap 3, I want a background to the page that is fixed to a container edge, so when resizing, the background moves with the container (ie, in the example below, the background image centered over the container edge):
(source: nfx.nz)
Is this possible with a background image, or would I have to add a new absolutely positioned layer / or javascript...?
There are several solutions to your question, and it really depends on if you require dynamic sizing of the background. The example I have shown will animate the container dynamically, so you can see how it works.
Approach No. 1: Offset background position with known value
One is if you know the exact dimensions of the image, then you can simply position it negatively along the x-axis (i.e. moving it to the left) by half the width of the image. This is assuming that you are not dynamically sizing your background image:
* {
margin: 0;
padding: 0;
}
div {
background-color: steelblue;
background-image: url('http://placehold.it/400x200');
background-repeat: no-repeat;
background-position: -200px 0;
width: 50%;
margin: 0 auto;
height: 500px;
animation-name: pulse;
animation-duration: 3s;
animation-iteration-count: infinite;
}
#keyframes pulse {
0% {
width: 50%;
}
50% {
width: 100%;
}
100% {
width: 50%;
}
}
<div>
Background image dimension: 400x200
</div>
Approach No. 2: Use pseudo/dummy element
If your background size is dynamic (i.e. changes with the size of the container), you are better off using an absolutely positioned pseudo-element or a dummy element:
* {
margin: 0;
padding: 0;
}
div {
background-color: steelblue;
width: 50%;
margin: 0 auto;
height: 500px;
animation-name: pulse;
animation-duration: 3s;
animation-iteration-count: infinite;
position: relative;
overflow: hidden;
}
div::before {
background-image: url('http://placehold.it/400x200');
background-repeat: no-repeat;
background-size: 100%;
content: '';
position: absolute;
top: 0;
bottom: 0;
left: -50%;
right: 50%;
}
div > * {
position: relative;
}
#keyframes pulse {
0% {
width: 50%;
}
50% {
width: 100%;
}
100% {
width: 50%;
}
}
<div>
<p>Background image dimension: 400x200</p>
</div>
I'm trying to absolutely center two elements in the middle of the page, with one behind the other. The intent is to have a page that is fully responsive with a circle in the middle which has a pulse effect behind it.
Here is a fiddle of the below:
html,
body {
height: 100%;
width: 100%;
}
body {
background: lightblue;
display: flex;
align-items: center;
justify-content: center;
}
.container {
display: flex;
align-items: center;
justify-content: center;
}
.sphere {
display: flex;
background: black;
border-radius: 300px;
height: 100px;
width: 100px;
}
.container:after {
display: flex;
background: #FFF;
border-radius: 300px;
height: 130px;
width: 130px;
animation: pulsate 2.5s ease-out;
animation-iteration-count: infinite;
opacity: 0.0;
content: "";
z-index: -1;
margin: auto;
}
#keyframes pulsate {
0% {
transform: scale(0.1, 0.1);
opacity: 0.0;
}
50% {
opacity: 1.0;
}
100% {
transform: scale(1.2, 1.2);
opacity: 0.0;
}
}
<div class="container">
<div class="sphere"></div>
</div>
Method:
I'm currently using flexbox to center a container div with a circle inside, and an :after tag on the container to create the pulse. I've tried using z-indexing (doesn't seem to do anything), and absolute positioning (which requires hard-coded px values which I'd like to stay away from).
Is there a graceful way to achieve this using flexbox?
Desired Effect:
This is close, but I'd like to move away from using px values for the :after element if possible.
Not sure if that'll do it, but you could simply add to your :after
position: absolute;
top : 0;
left : 0;
bottom: 0;
right : 0;
fiddle: http://jsfiddle.net/ccyd6xh1/
Update that was a quick draft, and was not absolutely responsive. If you want the effect the really follow your sphere and its size, you should add the :after on the sphere element and not its container, and use % width and height (here the glow grows to 130% of the sphere size):
http://jsfiddle.net/tjoo739y/
This is easily created with position: absolute, which removes the elements / pseudo elements from the normal flow of the document so they ignore each other. You can use flexible units and don't need to use px. There is no need for the flex properties to achieve this.
The .sphere element is given its height / width and is centered. The circles conform to this width / height and position.
Using a pseudo-element for the black circle is the easiest way to have it overlap the white pulsating circle. Both the circles are now siblings and the second sibling will overlap naturally
The pseudo-element children of .sphere are stretched to fit the parents height and width with the top / left / bottom / right properties set at 0.
One way to keep this responsive is to use a viewport width unit for the width and height. This will keep the height / width 1:1.
Example
body {
background: lightblue;
}
.sphere {
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
position: absolute;
height: 10vw;
width: 10vw;
}
.sphere:before,
.sphere:after {
position: absolute;
content: '';
border-radius: 50%;
left: 0;
right: 0;
bottom: 0;
top: 0;
}
.sphere:before {
background: #FFF;
animation: pulsate 2.5s ease-out infinite;
}
.sphere:after {
background: black;
}
#keyframes pulsate {
0%, 100% {
opacity: 0;
}
0% {
transform: scale(0.1, 0.1);
}
50% {
opacity: 1.0;
}
100% {
transform: scale(1.5, 1.5);
}
}
<div class="sphere"></div>