I have a plus sign that appears if you push the space button. But now it appears once. Can you help me to make it appear every time I press the space button? Here is my Code Pen.
import './style.scss';
let counter = 0;
document.addEventListener('keydown', ({ keyCode }) => {
const increment = document.getElementsByClassName('increment')[0];
if (keyCode === 32) {
counter++;
document.getElementsByClassName('counter')[0].innerText = counter;
increment.classList.remove('hidden');
increment.classList.add('move-increment');
}
});
.container {
/* ... */
.counter {
background-color: gray;
color: white;
border-radius: 10px;
padding: 10px;
}
.move-increment {
margin-top: -20px;
opacity: 0;
}
.hidden {
visibility: hidden;
}
.increment {
position: absolute;
margin-left: -33px;
z-index: 1;
transition: margin-top 1s cubic-bezier(0, 0.5, 0.5, 1),
opacity 1s ease-in-out;
}
}
Although I consider #ikiK's answer as the correct answer because the question was specifically about using CSS transitions, I would like to share a different approach. I think the goal of the 'plus' icon is to be displayed each time the counter increments. But when the counter increments while the transition of the previous increment is still playing it is impossible to display a second 'plus' symbol.
My suggestion would be to use some jQuery and, on each increment, append a new li item to an unordered list that is positioned right on top of the counter. Animate that li, fading it out to the top. And then use the callback function of animate() to remove the li element from the DOM once it has faded out of view.
let counter = 1;
$(document).on( 'keypress',function(e) {
if( e.which == 32 ) {
$('.counter').text(counter++);
let increment = $('<li><span class="increment">+</span></li>');
$('#increments').append(increment);
increment.animate({
opacity: 0,
top: '-=30px'
}, 500, function() {
increment.remove();
});
}
});
.container {
font-family: Arial, Helvetica, sans-serif;
font-size: 40px;
font-weight: bold;
display: flex;
height: 500px;
align-items: top;
justify-content: center;
position: relative;
overflow: hidden;
height: 100px;
}
.counter {
background-color: gray;
color: white;
border-radius: 10px;
padding: 10px;
}
#increments {
padding: 0px;
z-index: 1;
float: left;
margin-left: -33px;
list-style: none;
}
#increments li {
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<p>Counter: <span class="counter">0</span></p>
<ul id="increments"></ul>
</div>
Remove added .move-increment and add again removed hidden classes with slight delay, this will re-apply your transition: margin-top (read in provided links why delay):
setTimeout(function() {increment.classList.add('hidden');
increment.classList.remove('move-increment');}, 600);
Solution (changed key-code to arrow up: ↑ ):
let counter = 0;
document.addEventListener('keydown', ({
keyCode
}) =>
{
const increment = document.getElementsByClassName('increment')[0];
if (keyCode === 38) {
counter++;
document.getElementsByClassName('counter')[0].innerText = counter;
increment.classList.remove('hidden');
increment.classList.add('move-increment');
setTimeout(function() {
increment.classList.add('hidden');
increment.classList.remove('move-increment');
}, 600);
}
});
.container {
font-family: Arial, Helvetica, sans-serif;
font-size: 40px;
font-weight: bold;
display: flex;
height: 100px;
align-items: center;
justify-content: center;
}
.counter {
background-color: gray;
color: white;
border-radius: 10px;
padding: 10px;
}
.move-increment {
margin-top: -20px;
opacity: 0;
}
.hidden {
visibility: hidden;
}
.increment {
position: absolute;
margin-left: -33px;
z-index: 1;
transition: margin-top 1s cubic-bezier(0, 0.5, 0.5, 1), opacity 1s ease-in-out;
}
<div class="container">
<div>
Counter: <span class="counter">0</span>
<span class="increment hidden">+</span>
</div>
</div>
But however, this is not working perfectly when pressing key too fast. Try changing setTimeout duration and see what suits your need.
In links provided you have examples how to reset animation (not transition) all together and would solve this fast key press issues.
Read about this here, few really useful info's:
Restart CSS Animation
Controlling CSS Animations and Transitions with JavaScript
I think you don't need to hidden class, Simply you can use setTimeout for reset class, like this:
let counter = 0;
document.addEventListener("keydown", ({ keyCode }) => {
const increment = document.getElementsByClassName("increment")[0];
if (keyCode === 32) {
counter++;
document.getElementsByClassName("counter")[0].innerText = counter;
increment.classList.add("move-increment");
setTimeout(function () {
increment.classList.remove("move-increment");
}, 1000);
}
});
.container {
font-family: Arial, Helvetica, sans-serif;
font-size: 40px;
font-weight: bold;
display: flex;
height: 500px;
align-items: center;
justify-content: center;
}
.container .counter {
background-color: gray;
color: white;
border-radius: 10px;
padding: 10px;
}
.container .increment {
position: absolute;
margin-left: -33px;
z-index: 1;
visibility: hidden;
margin-top: 0;
opacity: 1;
transition: margin-top 1s cubic-bezier(0, 0.5, 0.5, 1), opacity 1s ease-in-out;
}
.container .increment.move-increment {
visibility: visible;
margin-top: -20px;
opacity: 0;
}
<div class="container">
<div>
Counter: <span class="counter">0</span>
<span class="increment">+</span>
</div>
</div>
Related
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.
I am trying to get a typewriter effect but emotes don't show up, long text doesn't wrap either. Feel free to ask more details I don't know if you need more info. Any help is appreciated.
I am trying to get a typewriter effect but emotes don't show up, long text doesn't wrap either. Feel free to ask more details I don't know if you need more info. Any help is appreciated.
Page is streamlabs you may need a twitch account
HTML Code
<!-- item will be appened to this layout -->
<div id="log" class="sl__chat__layout">
</div>
<!-- chat item -->
<script type="text/template" id="chatlist_item">
<div data-from="{from}" data-id="{messageId}">
<span class="meta" style="color: {color}">
<span class="badges">
</span>
<span class="name">{from}</span>
</span>
<span id="message">
{message}
</span>
</div>
</script>
Css Code
#import url('https://fonts.googleapis.com/css2?family=Codystar&display=swap');
* {
box-sizing: border-box;
}
html, body {
height: 100%;
overflow: hidden;
}
body {
text-shadow: 0 0 1px #000, 0 0 2px #000;
background: {background_color};
font-family: 'Codystar', cursive;
font-weight: 700;
font-size: {font_size};
line-height: 1.5em;
color: {text_color};
}
#log>div {
animation: fadeInRight .3s ease forwards, fadeOut 0.5s ease {message_hide_delay} forwards;
-webkit-animation: fadeInRight .3s ease forwards, fadeOut 0.5s ease {message_hide_delay} forwards;
}
.colon {
display: none;
}
#log {
display: table;
position: absolute;
bottom: 0;
left: 0;
padding: 0 10px 10px;
width: 100%;
table-layout: fixed;
}
#log>div {
display: table-row;
}
#log>div.deleted {
visibility: hidden;
}
#log .emote {
background-repeat: no-repeat;
background-position: center;
background-size: contain;
padding: 0.4em 0.2em;
position: relative;
}
#log .emote img {
display: inline-block !important;
height: 1em;
opacity: 0;
}
#log .message,#log .meta {
vertical-align: top;
display: table-cell;
padding-bottom: 0.1em;
}
#log .meta {
width: 35%;
text-align: right;
padding-right: 0.5em;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
#log .message {
word-wrap: break-word;
width: 65%;
}
#message {
word-wrap: break-word;
width: 65%;
}
.badge {
display: inline-block;
margin-right: 0.2em;
position: relative;
height: 1em;
vertical-align: middle;
top: -0.1em;
}
.name {
margin-left: 0.2em;
}
JavaScript Code
document.addEventListener('onLoad', function(obj) {
// obj will be empty for chat widget
// this will fire only once when the widget loads
});
document.addEventListener('onEventReceived', function(obj) {
// obj will contain information about the event
e++
typeEffect(e);
});
var speed = 50;
var e = 1;
function typeEffect(inp) {
var o = inp;
document.getElementById("message").id= "message"+o;
var text = $("#message"+o).text();
$("#message"+o).text('');
var i = 0;
var timer = setInterval(function() {
if(i < text.length) {
$("#message"+o).append(text.charAt(i));
i++;
}
else{
clearInterval(timer);
document.getElementById("message").id= "complete";
};
}, speed);
}
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>
$(".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');
});
My question is similar to this one : How can you make CSS on-hover content stay in place when you click or stop hovering using Javascript?
However, i did not understand well the solutions that were proposed.
So basically, i would like my CSS on-hover content to stay on top of my image when the user clicks on it. Could someone please tell me how to do so?
#core {
max-width: 960px;
margin-top: 25px;
}
ul.img-list {
list-style-type: none;
margin: 0;
padding: 0;
text-align: center;
}
ul.img-list li {
display: inline-block;
height: 120px;
margin: 0 1em 1em 0;
position: relative;
width: 120px;
}
span.background-content span {
display: table-cell;
text-align: center;
vertical-align: middle;
}
ul.img-list li:hover span.background-content {
opacity: 1;
}
span.background-content {
background: rgba(0, 0, 0, 0.5);
color: white;
cursor: pointer;
display: table;
height: 120px;
left: 0;
position: absolute;
top: 0;
width: 120px;
opacity: 0;
-webkit-transition: opacity 500ms;
-moz-transition: opacity 500ms;
-o-transition: opacity 500ms;
transition: opacity 500ms;
}
/* --------------------------------------------------------- */
span.title-content-platinum {
background: rgba(215, 215, 0, 0.8);
color: white;
cursor: pointer;
display: table;
height: 20px;
left: 0;
position: absolute;
top: -20px;
width: 120px;
}
span.title-content-platinum span {
display: table-cell;
text-align: center;
vertical-align: middle;
}
span.title-content-platinum {
background: rgba(215, 215, 0, 0.8);
color: white;
cursor: pointer;
display: table;
height: 20px;
left: 0;
position: absolute;
top: -20px;
width: 120px;
opacity: 0;
}
ul.img-list li:hover span.title-content-platinum {
opacity: 1;
}
span.title-content-platinum {
background: rgba(215, 215, 0, 0.8);
color: white;
cursor: pointer;
display: table;
height: 20px;
left: 0;
position: absolute;
top: -20px;
width: 120px;
opacity: 0;
-webkit-transition: opacity 500ms;
-moz-transition: opacity 500ms;
-o-transition: opacity 500ms;
transition: opacity 500ms;
}
<div id="core">
<ul class="img-list">
<li>
<a>
<a href="">
<img src="http://www.pokepedia.fr/images/thumb/e/e7/Pikachu-RFVF.png/120px-Pikachu-RFVF.png" alt="" width="120" height="120" />
</a>
<span class="title-content-platinum">Pikachu</span>
<span class="background-content"><span></span></span>
</a>
</li>
</ul>
</div>
I'm also learning Javascript (without Jquery for the moment), so a solution involving jscript would be much appreciated!
Here's a simple example using JS to add a CSS class to an element based on it's id. I use the HTML onclick attribute to call a javascript function, and pass in the HTML id to find the element and add the class. You should be able to adjust this to apply it to your situation.
Demo: http://jsfiddle.net/biz79/swxxLj3z/
Update: I've switched it to a toggleClass so that click1 adds the class and click2 removes the class. This code should be able to handle tags that have more than 1 class as well.
There's more elegant solutions on SO which you can look up, however, this will probably work for you in the meantime.
This looks like a good resource: Change an element's class with JavaScript
Anyways, just adjust to fit your purposes. Cheers!
HTML:
<div id='d1' onclick="toggleClass('d1')" class="class1 class2">Hello</div>
<div id='d2' onclick="toggleClass('d2')">there</div>
JS:
function toggleClass( ID ) {
var classToAdd = 'bigFont';
var el = document.getElementById(ID);
var classes = el.className;
var index = classes.indexOf(classToAdd);
if (index < 0) {
el.className += " " + classToAdd;
}
else {
classes = classes.replace(classToAdd, " ");
el.className = classes;
}
}
CSS:
div:hover {
font-size:2em;
}
.bigFont {
font-size:2em;
}
You'd first want to modify your css to take a class that denotes whether an item has been clicked
Here I use '.active-item'
ul.img-list li:hover span.background-content,
.active-item span.background-content
{
opacity: 1;
}
You'd then want to apply the active-item class using element.setAttribute() like so
var items = document.getElementByTagName("li");
for (index = 0; index < items.length; ++index) {
items[index].onmouseclick = function() {
items[index].setAttribute("class", "active-item");\
}
}