Transition happens instantly even though, I have duration time - css

Transition takes effect, but duration doesn't. How to fix the issue, and why does it happen?
Html
<article class="about-img">
<div class="about-picture-container">
<img src="./images/about-bcg.jpeg" alt="tea kettle" class="about-picture">
</div>
</article>
CSS
.about-picture-container {
background: var(--primaryColor);
border: 0.5rem solid var(--primaryColor);
border-radius: 1rem;
/* overflow */
overflow: hidden;
transition: all 0.3s ease-in-out;
}
.about-picture-container:hover .about-picture {
opacity: 0.5;
transform: scale(1.2);
}

You are setting the transition to one class .about-picture-container and applying the transform to another .about-picture.
Try changing your code to:
.about-picture-container .about-picture {
background: var(--primaryColor);
border: 0.5rem solid var(--primaryColor);
border-radius: 1rem;
/* overflow */
overflow: hidden;
transition: all 0.3s ease-in-out;
}
.about-picture-container:hover .about-picture {
opacity: 0.5;
transform: scale(1.2);
}

Related

Make blinking cursor disappear at end of CSS animation

I have a blinking cursor animation set up with two lines of text.
I want to have the cursor appear as the text appears, and vanish at the end of the first line – but leave it blinking at the end of the second line.
Someone asked a very similar question, but the solution makes the cursor completely invisible:
Stopping a blinking cursor at end of css animation
Tested this answer code (on several browsers), and it just doesn't work.
Here's what I have:
Code:
.typewriter1 p {
overflow: hidden;
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite;
}
.typewriter2 p {
overflow: hidden;
/* Ensures the content is not revealed until the animation */
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
opacity: 0;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite, slidein 1s ease 3.5s forwards;
animation-delay: 3.5s;
}
/* The typing effect */
#keyframes typing {
from {
width: 0
}
to {
width: 100%
}
}
#keyframes slidein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* The typewriter cursor effect */
#keyframes blink-caret {
from,
to {
border-color: #00aeff
}
50% {
border-color: transparent;
}
}
<div class="typewriter1">
<p>A well defined plan will identify problems,</p>
</div>
<div class="typewriter2">
<p> address challenges, and help restore confidence.</p>
</div>
Only Example 2 is fully explained at the moment. Example 3 is exactly the same HTML and CSS as the question with minor changes.
Example 1 — Redesign for background images and gradients
HTML
First, we can clean up the HTML. This is a single paragraph, so let's wrap it in one paragraph element:
<p class="typewriter">
A well defined plan will identify problems,
address challenges, and help restore confidence.
</p>
Second, we need to reveal each line individually, so we wrap each line in a nested span element and manually break the line with a line break:
<p class="typewriter">
<span class="slide">
<span class="inner-slide">A well defined plan will identify problems,
</span>
</span><br>
<span class="slide">
<span class="inner-slide">address challenges, and help restore confidence. </span>
</span>
</p>
Full Example 1
Current Limitation: We have to set a fixed pixel width for left.
.typewriter {
position: relative;
height: 500px;
margin: 0 auto;
width: 310px;
overflow: hidden;
}
.typewriter .slide,
.inner-slide {
display: inline-block;
overflow: hidden;
height: 1.1em;
}
.typewriter .slide {
position: relative;
animation: typing 2s steps(30, end) forwards, blink-caret .75s step-end infinite;
left: -310px;
border-right: .15em solid transparent;
}
.typewriter .slide:nth-of-type(1) {
animation: typing 2s steps(30, end) forwards, blink-caret .75s step-end 2.6;
}
.inner-slide {
position: relative;
animation: typing2 2s steps(30, end) forwards;
white-space: nowrap;
left: 310px;
}
.typewriter .slide:nth-of-type(2),
.typewriter .slide:nth-of-type(2) .inner-slide {
animation-delay: 2s;
}
#keyframes typing {
from {
left: -310px;
}
to {
left: 0;
}
}
#keyframes typing2 {
from {
left: 310px;
}
to {
left: 0;
}
}
/*The typewriter cursor effect */
#keyframes blink-caret {
0,
100% {
border-color: transparent
}
50% {
border-color: #00aeff
}
}
body {
background: linear-gradient(to bottom right, #CCC 0, #F00 100%) no-repeat;
}
<p class="typewriter">
<span class="slide">
<span class="inner-slide">A well defined plan will identify problems,
</span>
</span><br>
<span class="slide">
<span class="inner-slide">address challenges, and help restore confidence.</span>
</span>
</p>
Example 2 — Original. Suitable for solid colour backgrounds
The HTML
First, we can clean up the HTML. This is a single paragraph, so let's wrap it in one paragraph element:
<p class="typewriter">
A well defined plan will identify problems,
address challenges, and help restore confidence.
</p>
Second, we need to reveal each line individually, so we wrap each line in a span element and manually break the line with a line break:
<p class="typewriter">
<span>A well defined plan will identify problems,</span><br>
<span> address challenges, and help restore confidence.</span>
</p>
The CSS
Now we need an element that will cover our text and act as an animated cursor. We can use a pseudo-element that will start at 100% width and have a left border, like so:
.typewriter > span::before {
content: '';
border-left: .15em solid #00aeff;
position: absolute;
background: white;
height: 1.1em;
right: -5px;
width: 100%;
}
The height is just enough to cover all the text including below the baseline.
The right negative value will pull it outside its parent so the cursor doesn't show on the first line thanks to overflow-hidden on the parent.
It starts at 100% width which is animated to 0.
It is positioned absolute to the span which has a relative position.
In order to keep the cursor on the last line, we need to give it a 0 right value:
.typewriter > span:last-of-type::before {
right: 0;
}
Now it will no longer be pulled outside the parent.
The second line needs to be delayed by the same amount of time as the animation run time:
.typewriter > span:nth-of-type(2)::before {
animation-delay: 2s;
}
Because we want the paragraph widths to be determined by the width of the text and the span to accept widths, we need to make them inline-block:
.typewriter,
.typewriter > span {
display: inline-block;
}
Lastly, we reverse the typing animation to go from 100% to 0:
#keyframes typing {
from {
width: 100%
}
to {
width: 0
}
}
Full Example 2
.typewriter,
.typewriter > span {
display: inline-block;
}
.typewriter > span {
position: relative;
overflow: hidden;
padding-right: 4px;
}
.typewriter > span::before {
content: '';
position: absolute;
border-left: .15em solid #00aeff;
background: white;
height: 1.1em;
right: -5px;
width: 100%;
animation: blink-caret .75s step-end infinite, typing 2s steps(30, end) forwards;
}
.typewriter > span:nth-of-type(2)::before {
animation-delay: 2s;
}
.typewriter > span:last-of-type::before {
right: 0;
}
/* The typing effect*/
#keyframes typing {
from {
width: 100%
}
to {
width: 0
}
}
/*The typewriter cursor effect */
#keyframes blink-caret {
from,
to {
border-color: #00aeff
}
50% {
border-color: transparent
}
}
<p class="typewriter">
<span>A well defined plan will identify problems,</span><br>
<span> address challenges, and help restore confidence.</span>
</p>
Example 3 — Using exactly the example from the question
Change the iteration count as appropriate for the first line caret. In this example the value is 4.1. This animation will iterate 4.1 times and then stop:
animation: blink-caret .75s step-end 4.1
The border that creates the caret is changed to transparent:
border-right: .15em solid transparent
and the animation is flipped:
#keyframes blink-caret {
0,
100% {
border-color: transparent
}
50% {
border-color: #00aeff
}
}
Now the stopped state is transparent and the first line will disappear on the first line.
Full Example 3
body {
width: 330px;
}
.typewriter1 p {
overflow: hidden;
border-right: .15em solid transparent;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
padding-left: 10px;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end 4.1;
}
.typewriter2 p {
overflow: hidden;
/* Ensures the content is not revealed until the animation */
border-right: .15em solid transparent;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
padding-left: 10px;
opacity: 0;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite, slidein 1s ease 3.5s forwards;
animation-delay: 3.5s;
}
/* The typing effect */
#keyframes typing {
from {
width: 0
}
to {
width: 100%
}
}
#keyframes slidein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* The typewriter cursor effect */
#keyframes blink-caret {
0,
100% {
border-color: transparent
}
50% {
border-color: #00aeff
}
}
<div class="typewriter1">
<p>A well defined plan will identify problems,</p>
</div>
<div class="typewriter2">
<p> address challenges, and help restore confidence.</p>
</div>
I just changed infinite from .typewriter1 p { to 5.
.typewriter1 p {
overflow: hidden;
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end 5;
}
.typewriter2 p {
overflow: hidden;
/* Ensures the content is not revealed until the animation */
border-right: .15em solid #00aeff;
white-space: nowrap;
margin: 0 auto;
letter-spacing: 0;
color: #fff;
padding-left: 10px;
opacity: 0;
animation: typing 3.5s steps(40, end), blink-caret .75s step-end infinite, slidein 1s ease 3.5s forwards;
animation-delay: 3.5s;
}
/* The typing effect */
#keyframes typing {
from {
width: 0
}
to {
width: 100%
}
}
#keyframes slidein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* The typewriter cursor effect */
#keyframes blink-caret {
from,
to {
border-color: #00aeff
}
50% {
border-color: transparent;
}
}
<div class="typewriter1">
<p>A well defined plan will identify problems,</p>
</div>
<div class="typewriter2">
<p> address challenges, and help restore confidence.</p>
</div>
If you're not necessarily glued to writing your own animations for this, TypeIt's (https://typeitjs.com) API makes it possible w/ a lot less custom code:
https://codepen.io/alexmacarthur/pen/MWWEPxa
const secondInstance = new TypeIt('.typewriter2 p');
const firstInstance = new TypeIt('.typewriter1 p', {
afterComplete: function (instance) {
document.querySelector('.typewriter1 p .ti-cursor').remove();
secondInstance.go();
}
}).go();
The only downside to this approach is that you have less control over the animation itself (you'd need to override the CSS animation provided by the library).

CSS classes conflicting

I am trying to animate a card flipping face up and then fading out. I do this by adding a class 'flipped' on click and a second 'vanish' after a timeout of 2 seconds. However, as soon as the 'vanish' class is added, the card flips back face down. I don't understand why, as the 'flipped' class is still applied.
Here is my mark up:
<div class="grid-space">
<div class="card">
<div class="front-face">
<img src="https://res.cloudinary.com/lwcqviihu/image/upload/v1512898858/Animals/Sloth_svg.svg"/>
<p>sloth</p>
</div>
<div class="back-face"></div>
</div>
</div>
The CSS (flipped and vanish classes marked)
body {
background: #333;
}
.grid-space {
perspective: 1000;
width: 200px;
margin: auto;
}
.grid-space:hover {
transform: scale(1.02);
transition: 0.3s ease-in-out;
}
.card {
position: relative;
padding-bottom: 100%;
display: flex;
border-radius: 1vw;
transition: transform 0.4s ease-in-out, opacity 2s ease-in-out;
transform-style: preserve-3d;
cursor: pointer;
}
.card p {
color: inherit;
}
/*****These are the classes applied to do the animation***********/
.flipped {
transform: rotateY(180deg);
}
.vanish {
opacity: 0;
}
/*****END**********************************************************/
.front-face, .back-face {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
position: absolute;
width: 100%;
height: 100%;
border-radius: 1vw;
text-align: center;
box-sizing: border-box;
}
.front-face {
transform: rotateY(180deg);
color: #EDCB7A;
background: #487360;
border-style: solid;
border-width: 2px;
}
.back-face {
/* background: #C7C6C4;
border: 1px solid #EBD787; */
background: #3A295C;
border: 1px #EBD787 solid;
z-index: 10;
}
.front-face > p {
font-size: 3vmin;
margin: 0;
position: absolute;
bottom: 5%;
width: 100%;
text-align: center;
}
.front-face > img {
width: 90%;
margin-top: 5%;
}
And finally, the javascript:
window.onload = function() {
var card = document.getElementsByClassName('card')[0];
card.addEventListener('click', function() {
this.className += " flipped";
window.setTimeout(vanish, 2000);
});
function vanish() {
card.className += " vanish";
}
};
You can see the whole thing 'working' here: https://codepen.io/timsig/pen/MVavXv
Many thanks for any help.
There seems to be something odd hiding the revealed face when applying opacity to the parent.
I sinceriously don't know why that happens (if anyone has a clue, I'd really, really like to know), but an alternate approach would be to modify the faces instead of the card itself when you apply the .vanish class
.vanish > .back-face{
visibility:hidden;
}
.vanish > .front-face{
opacity:0
}
.front-face{
transition:opacity 2s ease-in-out;
}
and of course, taking out the rule that applies opacity 0 to the .card
/*.vanish {
opacity: 0;
}*/
I think I know why it's happening. When .card's opacity is being set to 0 because of .vanish, it's setting the opacity of its default state since the opacity style is being set on .card itself.
I fixed it by moving the opacity styles to .front-face since that's the side you want to fade out.
.card {
transition: transform 0.4s ease-in-out;
}
.vanish .front-face {
opacity: 0;
}
.front-face {
transition: opacity 2s ease-in-out;
}

Mouse hover delay, to show a child div

Using CSS transitions, I'd like to add a delay on hover, of 0.5s, in the class "activator".
After these 0.5s, it should change "content-l1" class from display:none to display:block
I've tried with this code, but doesn't work at all.
.content-l1 {
transition: 0s display;
}
.activator:hover>.content-l1 {
display: block;
transition-delay: 0.5s;
}
<div class="activator">
<div class="content-l1"> // initially: display:none whatever content here
</div>
</div>
display do not animation for transition. u can use opacity
.content-l1 {
transition: 0s;
opacity: 0;
}
.activator:hover>.content-l1 {
opacity: 1;
transition-delay: 0.5s;
}
<div class="activator">
fjhfjh
<div class="content-l1">
afsfas
</div>
</div>
but the block 'content-l1' takes place. we need use position
.activator {
position: relative;
}
.content-l1 {
position: absolute;
background-color: white;
padding: .4em;
border: 1px solid black;
transition: 0s;
opacity: 0;
}
.activator:hover>.content-l1 {
opacity: 1;
transition-delay: 0.5s;
}
<div class="activator">
fjhfjh
<div class="content-l1">
afsfas
</div>
</div>
qwewertrtw

How do I maintain the state of a hover on mouse out?

I am trying a transition where a line becomes a long rectangle. I want to make it so that when the transition finishes, the final state remains in place even when the mouse is not hovered on it.
This is my current code:
#line {
width: 300px;
height: 1px;
background-color: darkblue;
transition: height 2s;
-webkit-transition: height 2s;
}
#line:hover {
width: 300px;
height: 200px;
background-color: darkblue;
}
<div id="line"></div>
I think the best solution is to add a small script that adds a class. The class remains after unhovering:
window.addEventListener('DOMContentLoaded', function() {
document.getElementById('line').addEventListener('mouseover', function(event) {
document.getElementById('line').classList.add('activated');
});
});
#line {
width: 300px;
height: 1px;
background-color: darkblue;
transition: height 2s;
-webkit-transition: height 2s;
}
#line.activated{
width: 300px;
height: 200px;
background-color: darkblue;
}
<body>
<div id="line"></div>
</body>
A tricky way to get this effect only with CSS: set the transition-delay on the element to a huge value. and set it to 0 on the hover state
When you hover, the element changes to the hover state, and this way the transition is immediate.
When you un-hover, there will a 9999s delay before it begins (well, not really for ever, but nobody will notice)
#line {
width: 300px;
height: 10px;
background-color: darkblue;
-webkit-transition: height 1s 9999s;
transition: height 1s 9999s;
}
#line:hover{
width: 300px;
height: 200px;
background-color: darkblue;
-webkit-transition-delay: 0s;
transition-delay: 0s;
}
<body>
<div id="line"></div>
</body>

CSS how to change opacity of container but not text?

I am a complete newbie when it comes to HTML and CSS and just building my very first website. I want to create an image that, when hovered, displays text and fades the image to a lower opacity. I've got the fade all worked out, as well as the opacity change. My only issue is that the text, which is contained within the element I want to fade, also fades and I would like to keep it at 100% opacity. I have tried setting opacity to 1 for the text but it does not override the opacity change of its container. For example, I have:
<div class="textbox">
<p class="boxtext">This is the text that will eventually go inside the box. It is blah lljsd iofu isduf iou eiosu dfi eiou sdiofu ioe soidfu oidu foiu foisu doiu eoiusodidfu oei osidfuosdiu ieu oisduf oiueoisu dfoi oiu soifu iod fioeo dfs.</p>
</div>
And also
div.textbox {
background-color: white;
margin-left: 2.5vw;
border: 2px solid lightgray;
width: 15vw;
height: 600px;
float: left;
}
div.textbox:hover {
background-color: lightgray;
border: 2px solid lightgray;
opacity: 0.5;
}
p.boxtext {
margin: 5% 5%;
}
This creates the hover that I want, but I can't keep the text opacity at 100%.
Edit: Thank you for providing the rgba() solution, this solves the problem. I have another case of the same problem except that there is a background image instead of a solid background color. Is there a similar workaround?
Edit2: Issues with fade breaking after replacing opacity change with a separate transparent .png.
a#imglink1 {
background-image: url('https://www.profilesinhistory.com/wp-content/uploads/2012/11/Apollo-11-NASA-Photograph-Signed-Neil-Armstrong-Michael-Collins-Buzz-Aldrin-200x200.jpg');
width: 200px;
height: 200px;
float: left;
-o-transition: 0.5s;
-ms-transition: 0.5s;
-moz-transition: 0.5s;
-webkit-transition: 0.5s;
transition: 0.5s;
}
a#imglink1:hover {
background-image: url('../images/apollo_transparent.png');
-o-transition: 1s;
-ms-transition: 1s;
-moz-transition: 1s;
-webkit-transition: 1s;
transition: 1s;
}
a#imglink1:hover p {
visibility: visible;
}
Since you're using a solid background color you can use rgba to only change the opacity of the background/borders and not affect the content inside. In your example:
div.textbox:hover {
background-color: rgba(222,222,222,.5);
border: 2px solid rgba(222,222,222,.5);
}
https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgba()
For images you can accomplish a fade using :before and :after and fading the opacity of those elements:
a#imglink2 {
width: 200px;
height: 200px;
float: left;
position: relative;
}
a#imglink2 p
{
position: relative;
z-index:2;
}
a#imglink2:before
{
background-image: url('http://images2.layoutsparks.com/1/239061/welcome-orange-vintage-design.gif');
width: 200px;
height: 200px;
position: absolute;
top:0; left:0;
content:'';
z-index:1;
opacity:1;
transition: .3s opacity linear;
}
a#imglink2:after
{
background-image: url('http://images.all-free-download.com/images/graphicmedium/vintage_christmas_background_32295.jpg');
width: 200px;
height: 200px;
position: absolute;
top:0; left:0;
content:'';
z-index:1;
opacity:0;
transition: .3s opacity linear;
}
a#imglink2:hover:before
{
opacity:0;
}
a#imglink2:hover:after
{
opacity:1;
}
http://codepen.io/seraphzz/pen/ikJqB

Resources