conditional smooth CSS transition - javascript

Example Output
JSX code
<div>
<h3>Person</h3>
{isOnline &&<p>online</p>}
</div>
Need CSS for this Example Output

Css: i have a div with display flex which makes img and the span align horizontally, inside my span i have a h1 and a p tag.
for the h1 i have set some css properties and a transformY(10px) that means i am moving it up 10px from its original position.and a transition with time and animation type.
for the p i have also set some properties and a opacityof 0;
then i am just saying if my wrapper has a class of online in it then do this to h1 and p.
i am toggling that online class with a button for demo purpose. but in real life it can be with anything.
let wrapper = document.querySelector(".wrapper");
let btn = document.querySelector(".btn");
btn.addEventListener("click",()=>{
wrapper.classList.toggle("online")
})
.wrapper {
width: 510px;
height: 130px;
background-color: #017d68;
display: flex;
align-items: center;
padding: 10px;
gap: 30px;
}
img {
height: 120px;
border-radius: 100%
}
p {
font-size: 20px;
color: white;
opacity: 0;
transition: all 0.25s ease-in-out;
}
h1 {
font-family: Arial, Helvetica, sans-serif;
color: white;
transform: translateY(10px);
transition: all 0.25s ease-in-out;
}
.wrapper.online h1{
transform: translateY(-10px);
}
.wrapper.online p {
opacity: 1;
}
<div class="wrapper">
<img src="https://images.unsplash.com/photo-1493106819501-66d381c466f1?ixlib=rb- 1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80"
alt="">
<span>
<h1>Person</h1>
<p>online</p>
</span>
</div>
<button class="btn">Change Status</button>

Related

My UI animation is sloppy using javascript to add and remove animation classes—is there a better way?

I'm trying to make this news item component interface for a blog. Each item shows a story image and some of the text of the article. Rolling over the news item should "scrunch up" the image and reveal more of the text of the article. I can't see why my animation does not hold when you rollover the item, and then it resets completely before performing the "unscrunching."
There are keyframe animations that attach and detach to the item:
#keyframes scrunch {
from {
height: 50%;
}
to {
height: 10%;
}
}
#keyframes unscrunch {
from {
height: 10%;
}
to {
height: 50%;
}
}
.scrunch {
animation: scrunch 1s;
}
.unscrunch {
animation: unscrunch 1s;
}
Then I'm just adding and removing those classes from the news item class list:
const scrunchyBox = document.getElementById('scrunchyBox1');
const children = scrunchyBox.childNodes;
console.dir(children);
const scrunchyBoxHead = children[1];
scrunchyBox.addEventListener('pointerover', (event) => {
scrunchyBoxHead.classList.remove('unscrunch');
scrunchyBoxHead.classList.add('scrunch');
});
scrunchyBox.addEventListener('pointerout', (event) => {
scrunchyBoxHead.classList.remove('scrunch');
scrunchyBoxHead.classList.add('unscrunch');
});
Seems basic, but whatever I'm doing looks gross. Everything I've done is over at my Codepen.
You can use the transition property with the :hover pseudo-class. This will be the same that you have tryed to do with javascript.
To achieve this, just add few lines to your css file.
/* new block */
.scrunchyBox:hover .sectionHead {
height: 10%;
}
/* new block */
.scrunchyBox:hover .datedot {
transform: scale(0.45) translate(60px, -72px);
}
.scrunchyBox > .sectionHead {
transition: all 0.5s ease-in-out; /* new line */
}
.datedot {
transition: all 0.5s ease-in-out; /* new line */
}
body {
background-color: #ccc;
font-size: 18px;
}
.scrunchyBox {
color: #333;
position: relative;
background-color: #fff;
width: 400px;
height: 400px;
margin: 0 auto;
padding: 20px;
overflow: hidden;
filter: drop-shadow(4px 4px 4px #333);
}
/* new block */
.scrunchyBox:hover .sectionHead {
height: 10%;
}
/* new block */
.scrunchyBox:hover .datedot {
transform: scale(0.45) translate(60px, -72px);
}
.scrunchyBox > .sectionHead {
width: 400px;
height: 250px;
background-color: #3ab7f4;
padding: 0;
margin: 0 auto;
transition: all 0.5s ease-in-out; /* new line */
}
.datedot {
position: absolute;
top: 30px;
right: 30px;
background-color: rgba(0, 0, 0, 0.3);
padding: 12px;
border-radius: 60px;
width: 60px;
height: 60px;
transition: all 0.5s ease-in-out; /* new line */
}
.datedot > span {
font-family: 'Trebuchet MS', sans-serif;
color: rgba(255, 255, 255, 1);
text-align: center;
display: block;
margin: 0;
}
.datedot > span.day {
font-size: 2.2em;
font-weight: bold;
line-height: 0.8em;
padding: 0;
}
.datedot > span.month {
font-size: 1.3em;
font-weight: normal;
text-transform: uppercase;
padding: 0;
}
.scrunchyBox > h2 {
font-family: 'Trebuchet MS', sans-serif;
font-size: 1.2em;
line-height: 1em;
padding: 0;
}
.scrunchyBox > p {
font-family: 'Georgia', serif;
font-size: 1.4em;
}
<div id="scrunchyBox1" class="scrunchyBox">
<div class="sectionHead">
<div class="datedot">
<span class="day">30</span>
<span class="month">Oct</span>
</div>
</div>
<h2>A Headline for the Scrunchy Box</h2>
<p>
This is some text that would normally be some text that the reader would want to see more of. It gets cut off here by other elements, but then other elements "scrunch" in order to reveal more of the text for a preview.
</p>
</div>
You can retain the animation in its final state using animation-fill-mode: forwards; as described in answer to this question: Maintaining the final state at end of a CSS3 animation
It will still look janky if you remove pointer from the box mid-animation. I am not sure why you don't want to simply use CSS :hover with transition.

Centering Text in a Span tag not working as required

const spans = document.querySelectorAll("span");
const animation = function () {
for (let span of spans) span.classList.toggle("fade");
};
//setInterval(animation, 2400);
.animated {
font-size: 40px;
color: #d1d8e0;
margin-top: 20px;
font-weight: 900;
height: 60px;
line-height: 50px;
}
.animated span {
opacity: 1;
transition: all 0.5s;
}
.animated>.fade {
opacity: 0;
}
#media (max-width: 800px) {
.animated {
height: 70px;
font-size: 25px;
}
}
<div class="animated">
Hey, I'm<br>
<span class="color-primary fade" id="animated-name">Name Name</span>
<span class="color-primary" id="animated-text">Description about something <br>Text & Text</span>
</div>
I am trying to align text to the center of the page and to be responsive for all devices.
I have tried several option but none of them worked:
Trial No.1:
added style="margin:auto; in the span
Trial No.2:
added style="margin-left:-188; in the span
Trial No.3:
added style="text-align: center;" in the div before the span
Trial No.4
added position: absolute; in the animated span
In the home.html
<div class="animated">
Hey, I'm<br>
<span class="color-primary fade" id="animated-name">Name Name</span>
<span class="color-primary" id="animated-text">Description about something</br>Text &
Text</span>
</div>
In the css
.animated {
font-size: 40px;
color: #d1d8e0;
margin-top: 20px;
font-weight: 900;
height: 60px;
line-height: 50px;
}
.animated span {
opacity: 1;
transition: all 0.5s;
}
.animated>.fade {
opacity: 0;
}
#media (max-width: 800px) {
.animated {
height: 70px;
font-size: 25px;
}
}
In the base.html
<script>
const spans = document.querySelectorAll("span");
const animation = function () {
for (let span of spans) span.classList.toggle("fade");
};
setInterval(animation, 2400);
</script>
My question is how to cetner the text in the span and when there are long sentences similar to the second span to be also centered
If you want to leave your span as is, set it to the following:
.animated span {
opacity: 1;
transition: all 0.5s;
display: block;
}
You could use display: grid to achieve that.
Change your span elements to div (you probably should give those a class to make the CSS clearer)
grid-area: 1 / 1 / 1 / 1; for both of those div ensures that they both overlap.
margin: auto; ensures that they are centered. And text-align: center; that the text itself is centered.
const spans = document.querySelectorAll(".grid > div");
const animation = function() {
for (let span of spans) span.classList.toggle("fade");
};
setInterval(animation, 2400);
.animated {
font-size: 40px;
color: #d1d8e0;
margin-top: 20px;
font-weight: 900;
height: 60px;
line-height: 50px;
}
.animated .grid div {
opacity: 1;
transition: all 0.5s;
}
.animated .grid .fade {
opacity: 0;
}
#media (max-width: 800px) {
.animated {
height: 70px;
font-size: 25px;
}
}
.grid {
display: grid;
}
.grid>div {
grid-area: 1 / 1 / 1 / 1;
margin: auto;
text-align: center;
}
<div class="animated">
Hey, I'm<br>
<div class="grid">
<div class="color-primary fade" id="animated-name">
Name Name
</div>
<div class="color-primary" id="animated-text">
Description about something<br>Text & Text
</div>
</div>
</div>
start with placing text-align:center on the div. Not really clear exactly how you want to display
const spans = document.querySelectorAll("span");
const animation = function () {
for (let span of spans) span.classList.toggle("fade");
};
setInterval(animation, 2400);
.animated {
font-size: 40px;
color: #d1d8e0;
margin-top: 20px;
font-weight: 900;
height: 60px;
line-height: 50px;
text-align:center;
}
.animated span {
opacity: 1;
transition: all 0.5s;
}
.animated>.fade {
opacity: 0;
}
#media (max-width: 800px) {
.animated {
height: 70px;
font-size: 25px;
}
}
<div class="animated">
Hey, I'm<br>
<span class="color-primary fade" id="animated-name">Name Name</span>
<span class="color-primary" id="animated-text">Description about something <br>Text & Text</span>
</div>

How to cut exceeded content of div inside another div?

I'm trying to create a "bubble" which gets bigger in order to change its parent color with a nice animation. I like my approach, but I only need to put it inside the parent div.
This is what I have:
HTML
<html>
<body>
<div class="nav-menu" style="top: -64px;">
<div class="test"></div>
<div class="brand" onclick="test();">
<h1>App</h1>
</div>
<ul class="menu-list">
<li class="menu-item">Item</li>
</ul>
</div>
</body>
</html>
CSS
#import url('https://fonts.googleapis.com/css2?family=Satisfy&display=swap');
* {
margin: 0;
padding: 0;
}
.nav-menu {
z-index: 1000;
padding: 0 16px;
display: flex;
justify-content: space-between;
background-color: #B67171;
color: white;
position: fixed;
width: 100%;
transition: background-color .5s, top .2s;
}
.test {
background-color: blue;
position: absolute;
border-radius: 50%;
z-index: -1;
width: 32px;
height: 32px;
left: 50%;
top: 50%;
transform: scale(0) translate(-50%, -50%);
transform-origin: top left;
transition: transform .25s;
}
.nav-menu .brand h1 {
margin: 0;
padding: 0;
line-height: 64px;
font-family: 'Satisfy', cursive;
}
.nav-menu .menu-list {
list-style: none;
margin: 0;
}
.nav-menu .menu-list a {
display: inline-block;
margin: 0;
padding: 0 16px;
line-height: 64px;
font-size: 21px;
vertical-align: middle;
transition: background-color .2s;
color: white;
text-decoration: none;
}
.nav-menu .menu-list a:hover {
background-color: #D8C292;
}
(And a .js just for testing)
let navMenu = document.getElementsByClassName("nav-menu")[0];
window.addEventListener('load', function (e) { navMenu.style.top = "0"; });
var showing = false;
function test () {
document.getElementsByClassName("test")[0].style = "transform: scale(" + (showing ? 0 : 4) + ") translate(-50%, -50%);";
showing = !showing;
}
Here you have a demo in which you can press the "App" text and it would scale the "bubble" just a little bit. I want to remove the following stuff:
Can anybody give me a hint? However if you know any better solution for this "feature", I will appreciate it.
Thank you in advance!
Adding overflow:hidden property to your navigation div would work. Try this code.
.nav-menu {
z-index: 1000;
padding: 0 16px;
display: flex;
justify-content: space-between;
background-color: #B67171;
color: white;
position: fixed;
width: 100%;
transition: background-color .5s, top .2s;
overflow: hidden;
}
Add to .navmenu property overflow
DOC: overflow
nav-menu {
...
overflow: hidden;
}
Simply add overflow: hidden; to your div with class nav-menu.
Here is your edited example: https://jsfiddle.net/4r1n2cux/2/
use overflow: hidden; in style of first <div>

CSS pointer-events: none while allowing hover

I'm trying to create an element of top my page which can be hovered. When hovered I want to change the opacity of the element and allow click through.
The thing is when I add the pointer-events: none to allow the click through, my hover is never triggered, which seems logic after all. I though I would be able to deal with it with JavaScript, but event mouseover or mouseenter is not compatible with pointer-events: none.
Here is my example with only CSS: If I add the pointer-events: none; it doesn't work. The element is the red banner, I want to be able to click the buttons underneath while being able to lower the opacity of it.
body {margin:0; padding:0;}
.title {font-weight:bold;margin-right:10px;}
.container {margin: 0 auto;width:80%;position:relative;overflow:hidden;}
.content {height:300px;border: 1px solid #c8c8c8;}
nav {background-color:#efebe0;padding:20px;}
button {padding:10px;background-color:#9ebf00;border: 1px solid #86a200;border-radius:5px;margin: 0 5px 0 5px;}
button.right {float:right;}
.bandeau {
position: absolute;
background: red none repeat scroll 0% 0%;
width: 300px;
height: 40px;
z-index: 2;
font-size: 30px;
color: white;
font-weight: bold;
text-align: center;
right: -70px;
transform: rotate(45deg);
top: 60px;
display: block;
transition: 0.2s ease-in-out;
pointer-events:none;
}
.bandeau:hover {
opacity: 0.4;
}
<div class="container">
<nav>
<span class="title">Dummy Example</span>
<button>Home</button>
<button>Pricing</button>
<button class="right">Contact us</button>
<button class="right">Log in</button>
</nav>
<div class="content"></div>
<div class="bandeau">
<span>I will be back !</span>
</div>
</div>
The other example with JavaScript:
document.addEventListener('DOMContentLoaded', function() {
var bandeau = document.getElementById("bandeau");
bandeau.addEventListener('mouseenter', e => {
bandeau.style.opacity = '0.4';
bandeau.style.pointerEvents = 'none';
});
bandeau.addEventListener('mouseleave', e => {
bandeau.style.opacity = '1';
bandeau.style.pointerEvents = 'auto';
});
}, false);
body {margin:0; padding:0;}
.title {font-weight:bold;margin-right:10px;}
.container {margin: 0 auto;width:80%;position:relative;overflow:hidden;}
.content {height:300px;border: 1px solid #c8c8c8;}
nav {background-color:#efebe0;padding:20px;}
button {padding:10px;background-color:#9ebf00;border: 1px solid #86a200;border-radius:5px;margin: 0 5px 0 5px;}
button.right {float:right;}
#bandeau {
position: absolute;
background: red none repeat scroll 0% 0%;
width: 300px;
height: 40px;
z-index: 2;
font-size: 30px;
color: white;
font-weight: bold;
text-align: center;
right: -70px;
transform: rotate(45deg);
top: 60px;
display: block;
transition: 0.2s ease-in-out;
}
<div class="container">
<nav>
<span class="title">Dummy Example</span>
<button>Home</button>
<button>Pricing</button>
<button class="right">Contact us</button>
<button class="right">Log in</button>
</nav>
<div class="content"></div>
<div id="bandeau">
<span>I will be back !</span>
</div>
</div>
Is there a way to achieve this or is it impossible?
In your example you could do it easily on a hover on the whole nav element like
nav:hover + .content + .bandeau { opacity: 0.4; }
Or you can move the banner element to the because it's an absolute positioned element. Then a hover on the login button (with the .right class) will make it transparent:
body {margin:0; padding:0;}
.title {font-weight:bold;margin-right:10px;}
.container {margin: 0 auto;width:80%;position:relative;overflow:hidden;}
.content {height:300px;border: 1px solid #c8c8c8;}
nav {background-color:#efebe0;padding:20px;}
button {padding:10px;background-color:#9ebf00;border: 1px solid #86a200;border-radius:5px;margin: 0 5px 0 5px;}
button.right {float:right;}
.bandeau {
position: absolute;
background: red none repeat scroll 0% 0%;
width: 300px;
height: 40px;
z-index: 2;
font-size: 30px;
color: white;
font-weight: bold;
text-align: center;
right: -70px;
transform: rotate(45deg);
top: 60px;
display: block;
transition: 0.2s ease-in-out;
pointer-events:none;
}
.right:hover + .bandeau {
opacity: 0.4;
}
<div class="container">
<nav>
<span class="title">Dummy Example</span>
<button>Home</button>
<button>Pricing</button>
<button class="right">Contact us</button>
<button class="right">Log in</button>
<div class="bandeau">
<span>I will be back!</span>
</div>
</nav>
<div class="content"></div>
</div>
I know it's a bit different than a hover on the banner itself, but maybe this can give you some ideas :)
I found a solution based on a comment on the thread linked by #yanca.
I use document.elementFromPoint to chekc what cursor I should display (pointer or auto) based on the lement below the banner. Then I reuse document.elementFromPoint to transfer the click through
Here is the code :
document.addEventListener('DOMContentLoaded', function() {
var bandeau = document.getElementById("bandeau");
bandeau.addEventListener('mousemove', e => {
bandeau.style.display = "none";
var elemUnder = document.elementFromPoint(e.clientX, e.clientY);
bandeau.style.display = "block";
var stylesUnder = getComputedStyle(elemUnder);
bandeau.style.cursor = stylesUnder.cursor;
});
bandeau.addEventListener('click', e => {
bandeau.style.display = "none";
var elemUnder = document.elementFromPoint(e.clientX, e.clientY);
bandeau.style.display = "block";
elemUnder.click();
});
}, false);
body {margin:0; padding:0;}
.title {font-weight:bold;margin-right:10px;}
.container {margin: 0 auto;width:80%;position:relative;overflow:hidden;}
.content {height:300px;border: 1px solid #c8c8c8;}
nav {background-color:#efebe0;padding:20px;}
button {padding:10px;background-color:#9ebf00;border: 1px solid #86a200;border-radius:5px;margin: 0 5px 0 5px;cursor:pointer;}
button.right {float:right;}
#bandeau {
position: absolute;
background: red none repeat scroll 0% 0%;
width: 300px;
height: 40px;
z-index: 2;
font-size: 30px;
color: white;
font-weight: bold;
text-align: center;
right: -70px;
transform: rotate(45deg);
top: 60px;
display: block;
transition: 0.2s ease;
}
#bandeau:hover {
opacity:0.4;
transition: 0.2s ease;
}
<div class="container">
<div id="body">
<nav>
<span class="title">Dummy Example</span>
<button>Home</button>
<button>Pricing</button>
<button class="right" onclick="alert('click contact')">Contact us</button>
<button class="right" onclick="alert('click login')">Log in</button>
</nav>
<div class="content"></div>
<div>
<div id="bandeau">
<span>I will be back !</span>
</div>
</div>
Thanks for the help !!

how to slowly show element in vanilla js? My main concern is to show this element slowly

$(".warning").show("slow");
body {
background: #2d3339
}
.warning {
border: 5px solid #e1dfbe;
width: 200px;
margin: 100px auto 20px;
border-radius: 5px;
padding: 20px 10px;
text-align: center;
font-size: 32px;
display: none;
}
.warning span {
color: #f4f3ce;
font-family: sans-serif;
font-weight: bold;
}
.image {
position: absolute;
top: 20%;
width: 100%;
text-align: center;
z-index: -1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="warning">
<span>Lorem ips</span>
</p>
how to write $(".className").show("slow") in vanilla js? My main concern is to show this element slowly.
like this in jquery
Do you want some kind of fade effect? You can try doing something with CSS transitions to change the opacity. Take a look at this JSFiddle. You can make it slower/faster by changing the amount of time the transition takes.
HTML:
<p id="my-para">Hello, my name is John</p>
<button id="btn">Show Element</button>
CSS:
p {
opacity: 0;
}
.fade-in {
opacity: 1;
transition: opacity .9s ease;
}
JS:
var btn = document.getElementById('btn');
btn.addEventListener('click', function() {
document.getElementById('my-para').classList.add('fade-in');
});

Categories

Resources