curtain effect on text only - text showing from middle to outer edges - html

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>

Related

Making text 'appear' but with a picture background

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?

Smooth animation loop for horizontal text scroll

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.

On hover animate a html element along the parent element boundaries/path

Is it possible to on hover animate an html element (a div) along the boundary of a parent element (a div)? Actually I have kind of answered the first part of this question, but I am having trouble getting the animation to occur from a certain point, then animate back to the starting point on mouse off. I may be trying to push CSS a little too far. But is this possible? If you notice in the sample code when you mouseover the little box jumps to the corner and starts animating smoothly, then off mouse off it abruptly snaps to back to the original position. I have tried animating the position attribute as well, still no go. This is the closest I have been able to get.
html, body {
height: 100%;
background-color: #000000;
color: #ffffff; }
.container {
height: 100%;
display: flex;
border: 1px solid green;
align-items: center;
justify-content: center; }
.container > div {
position: relative;
text-align: center; }
.sqwr-orbit {
height: 10px;
width: 10px;
background: #ffffff;
margin: 0 auto; }
.ignite:hover #square {
animation-duration: 12s;
animation-name: squareorbit;
animation-timing-function: linear;
animation-iteration-count: infinite; }
#keyframes squareorbit {
0% {
margin: 0 50% 0 0; }
25% {
margin: 90% 0 0 0; }
50% {
margin: 90% 0 0 90%; }
75% {
margin: 0 0 0 90%; }
100% {
margin: 0;
transform: rotateZ(1800deg); } }
<div class="container">
<div>
<div class="ignite" style="padding: 5px;height: 100px; width: 100px; position: relative;">
<div class="sqwr-orbit" id="square"></div>
<div style="position: absolute; border: 1px solid #fff; top: 8px; left: 10px; width: 80%; height: 84%;">
</div>
</div>
</div>
</div>
example image

How to center a absolute element in another absolute element, that could be used for rotation and animation purposes

To make it clear, I have two squares they both have position: absolute and are inside another div that has a relative position.
This is related more to a UI design and not about centering two divs into each other and use if for web, it's more a UI thing or an animation thing for popups or similar.
That means it could be that I have a circle that is bigger than box1 somewhere. Then I use an invisible box that has position relative that contains box2 as a child
Both of the squares have a different size.
New example of issue here: https://jsfiddle.net/mgznef98/2/
The red box is not allowed to change position The border somehow has to be centered. And I put it inside a box2-container to support it, because box1 could be another shape and not a simple box if I would edit it
"some-container" is just the "thing" that would move around the website and carry all of the "boxes", so it can't be used with table-cell.
If you would look at this Rotate objects around circle using CSS?
On this page they rotate elements around the center of another element, but they're not inside the center. And I'm trying to put something in a center. That would be as example a square with a border that would rotate around.
I've managed to center the blue square inside the red square, somehow. I'm not even sure if it is exactly centered. https://jsfiddle.net/mgznef98 on this one before, but for the border one, I don't really know.
My question is, I think there is some math behind it. I think there has to be some formula to find out what to put inside "top" and "left" so I can center the blue "border" box exactly inside the red box when the red box changes the width and height.
What I know is that it changes depending on the size of box2 and its container and box1.
Example:
Let's say again I have two boxes but one of them is invisible, in this case the container of box2. And box2 is not a box instead it is "something" that rotates. And box1 is not a box, instead it is an element a shape or something that has a center. And box2 has a border instead of a background color, and that border has to rotate around the center of the element. The thing is that box2 is bigger than box1.
.some-container {
top: 30px;
left: 30px;
position: relative;
}
.box1 {
width: 20px;
height: 20px;
background: red;
position: absolute;
}
.box2-container {
position: relative;
height: 20px;
width: 20px;
}
.box2 {
width: 40px;
height: 40px;
border: 2px solid blue;
position: absolute;
top: -50%; /* These values have to be changed when I want to recenter a new width and height from box1 */
left: -50%;
border-radius: 50%;
border-color: blue blue blue transparent;
border-width: 2px;
animation: box2-rotation 3s linear infinite;
}
#keyframes box2-rotation {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
<div class=some-container>
<div class=box1>
</div>
<div class=box2-container>
<div class=box2>
</div>
</div>
</div>
I think this is what you wanted.
https://jsfiddle.net/5zun4tqr/
I've used the example from there: Center element inside div (circle)
It will always remain in the center like that, size shouldn't cause any problems when used with that flexbox method.
body {
background: #0a0a0a;
}
.some-container {
position: relative;
display: inline-block;
}
.some-container2 {
position: relative;
display: inline-block;
margin-left: 80px;
}
.some-container3 {
position: relative;
top: 30px;
left: 30px;
}
.box1 {
width: 50px;
height: 50px;
background: red;
position: absolute;
}
.box2-container {
display: flex;
position: relative;
height: 50px;
width: 50px;
justify-content: center;
align-items: center;
border: darkgreen solid 1px;
box-sizing: border-box; /* Because of the border */
}
#keyframes box2-rotation {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
.box2 {
width: 40px;
height: 40px;
border: 2px solid blue;
position: absolute;
border-radius: 50%;
border-color: blue blue blue transparent;
border-width: 2px;
animation: box2-rotation 3s linear infinite;
}
.replace1 {
width: 30px;
height: 30px;
}
.replace2 {
width: 30px;
height: 30px;
}
.replace3 {
width: 60px;
height: 60px;
}
.box3 {
width: 80px;
height: 80px;
border: 2px solid;
position: absolute;
border-radius: 50%;
border-color: green green green transparent;
border-width: 2px;
animation: box2-rotation 4s linear infinite;
}
.box4 {
width: 120px;
height: 120px;
position: absolute;
animation: box4-rotation 6s linear infinite;
}
#keyframes box4-rotation {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
.box4-circle {
stroke-dasharray: 52.275;
stroke-width: 2px;
animation: box4-rotateion 6s linear infinite;
animation-fill-mode: both;
transform-origin: center;
}
<div class=some-container3>
<div class=some-container>
<div class=box1>
</div>
<div class=box2-container>
<div class=box2>
</div>
</div>
</div>
<div class=some-container2>
<div class="box1 replace1">
</div>
<div class="box2-container replace2">
<div class="box2 replace3"></div>
<div class="box3"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 107 107" class="box4">
<circle class="box4-circle" cy=50% cx=50% r=50 stroke=white fill=none></circle>
</svg>
</div>
</div>
</div>
</div>
Personally I wouldn't do it with absolute positions if all you are doing is trying to center a div within another. Doing some like this with flex will perfectly center your box 2 within box 1.
<div>
<div class=box1>
<div class=box2>
</div>
</div>
.box1 {
width: 40px;
height: 40px;
background: red;
display: flex;
justify-content: center;
align-items: center;
}
.box2 {
width: 20px;
height: 20px;
background: blue;
}

CSS: How to accomplish a div which is blurred at the edges?

I have an idea for an Ajax-loader.
This is what I have accomplished so far:
body {
background-color: lightGrey;
counter-reset: h1-counter;
}
.wrap {
max-width: 200px;
height: 50px;
margin: 50px auto;
position: relative;
overflow: hidden;
}
.wrap div {
background: linear-gradient(#0032f0, white, #0032f0);
position: absolute;
width: 100%;
height: 100%;
z-index: 1000;
opacity: .8;
}
.wrap div.dark-bar {
position: absolute;
width: 10%;
height: 100%;
animation: moveDarkBar 3s linear infinite;
z-index: 1;
}
#keyframes moveDarkBar {
from {
left: -20%;
}
to {
left: 120%;
}
}
<div class="wrap">
<div></div>
<div class="dark-bar"></div>
</div>
I want the moving indicator (.dark-bar) to be "melted" with foreground-div. Currently there is a hard line which is visually distinguishable.
Is there a way to get the moving indicator (.dark-bar) to be blurred on the left-, right edge?
You could make use of CSS filter to add blur to top layer which is animated as below,
filter - The filter property provides graphical effects like blurring,
sharpening, or color shifting an element. Filters are commonly used to
adjust the rendering of images, backgrounds, and borders.
Do include vendor prefixes for other browsers such as -webkit-,-o-,-moz-,-ms- to filter.
body {
background-color: lightGrey;
counter-reset: h1-counter;
}
.wrap {
max-width: 200px;
height: 50px;
margin: 50px auto;
position: relative;
overflow: hidden;
}
.wrap div {
background: linear-gradient(#0032f0, white, #0032f0);
position: absolute;
width: 100%;
height: 100%;
z-index: 1000;
opacity: .8;
}
.wrap div.dark-bar {
position: absolute;
width: 10%;
height: 100%;
animation: moveDarkBar 3s linear infinite;
z-index: 1;
-webkit-filter:blur(2px); /*Add this*/
}
#keyframes moveDarkBar {
from {
left: -20%;
}
to {
left: 120%;
}
}
<div class="wrap">
<div></div>
<div class="dark-bar"></div>
</div>
Try using the box-shadow property and set the vertical and horizontal axis values to 0. Something like this:
div {
box-shadow: 0 0 10px black;
}
This might be a similar effect for the one you want.