css bubble chat slide up animation - css

I'm trying to create chat animation using CSS only. So far, I have tried creating this. My question is how to hide a bubble when it's not their time to show up?
#keyframes slide {
from {bottom: -20px}
to {bottom: 0px}
0% { opacity: 0; }
100% { opacity: 1; }
}
Also, I figured that this is not the best approach to create chat animation. I still haven't thought about how to hide the older bubble chat when the chat is getting longer. Does anyone know what's the best approach to create this animation but using CSS only?

The key idea is to use a flexbox container which flex-direction: column-reverse so the messages are always bottom-anchored. Doing so you need to insert the markup of the whole chat in reverse order.
The container has a ::before pseudoelement stacked on top with a gradient as a background, so, while the conversation is scrolling, the messages seem to disappear on the top area.
The animation on the messages can be done using a different animation-delay for each message and animation-fill-mode: forwards to keep the values of the last keyframe.
*, *::before {
box-sizing: border-box;
}
.chat {
display: flex;
flex-direction: column-reverse;
height: 12rem;
overflow: hidden;
border: 1px #ccc dashed;
font: .85rem/1.5 Arial;
color: #313131;
position: relative;
}
.chat::before {
content: "";
position: absolute;
z-index: 1;
top: 0;
height: 40%;
width: 100%;
background: linear-gradient(to bottom, white 20%, rgba(255, 255, 255, 0)) repeat-x;
}
.chat p {
margin: 0;
padding: 0;
}
.chat__content {
flex: 0 1 auto;
padding: 1rem;
margin: 0 0.5rem;
background: var(--bgcolor);
border-radius: var(--radius);
}
.chat__message {
width: 45%;
display: flex;
align-items: flex-end;
transform-origin: 0 100%;
padding-top: 0;
transform: scale(0);
max-height: 0;
overflow: hidden;
animation: message 0.15s ease-out 0s forwards;
animation-delay: var(--delay);
--bgcolor: #d8d8d8;
--radius: 8px 8px 8px 0;
}
.chat__message_B {
flex-direction: row-reverse;
text-align: right;
align-self: flex-end;
transform-origin: 100% 100%;
--bgcolor: #d2ecd4;
--radius: 8px 8px 0 8px;
}
.chat__message::before {
content: "";
flex: 0 0 40px;
aspect-ratio: 1/1;
background: var(--bgcolor);
border-radius: 50%;
}
#keyframes message {
0% {
max-height: 100vmax;
}
80% {
transform: scale(1.1);
}
100% {
transform: scale(1);
max-height: 100vmax;
overflow: visible;
padding-top: 1rem;
}
}
<section class="chat">
<div class="chat__message chat__message_B" style="--delay: 18s;">
<div class="chat__content">
<p>Thank you.</p>
</div>
</div>
<div class="chat__message chat__message_A" style="--delay: 13s;">
<div class="chat__content">
<p>Mr.Doe, your current balance is $19,606.76</p>
</div>
</div>
<div class="chat__message chat__message_A" style="--delay: 10s;">
<div class="chat__content">
<p>Sure, let me check...</p>
</div>
</div>
<div class="chat__message chat__message_B" style="--delay: 6s;">
<div class="chat__content">
<p>Hi jane, I'm John Doe. <br />
I need to know my current account balance</p>
</div>
</div>
<div class="chat__message chat__message_A" style="--delay: 1s;">
<div class="chat__content">
<p>Hello, my name is Jane.<br />
How can I help you?</p>
</div>
</div>
</section>

Related

How to create a CSS slide loop that is smoth

i need some help with a css slide loop,
Its working but the slide is not smooth, there is a jittering and there is a jump at the end the loop.
I kept changing the keyframe but i just cant find a way to make is smooth without jittering
So here's the code :
thats the container :
.container {
max-width: 1140px;
position: relative;
width: 100%;
margin: auto;
text-align : center ;
overflow : hidden;
}
// here the column where the images slides
.col-lg-3 {
animation: slide 15s linear infinite;
margin: 20px 5px ;
}
#keyframes slide {
0% {transform: translate(0)}
100% { transform: translateX(calc(-250px * 5))}
}
Pretty sure that there must be a better solution. But you need to ask better question i think.
I still don't know what do you need, but check this maybe it will help.
I create a box full of images and give that box a margin-left (comes from justify content: end inside parent container(main-container)) and cover it with another box (cover-container) which have a position:absolute on it. and have a higher z-index than main-container and same background-color with main-container.
In animation i gave
100% {
transform: translateX(-600%);
}
-600% because i have 5 images and when i give 5 width it acts like it is jumping as you said in your question but when giving 600% (5 + 1) it acts better like continious loop.
img{
display: block;
max-width: 100%;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
body{
min-height: 100vh;
overflow: hidden;
position: relative;
margin:0;
}
.container {
max-width: 1200px;
display: grid;
place-content: center;
margin: 0 auto;
background-color: bisque;
height: 100vh;
}
.main-container{
display: flex;
overflow : hidden;
justify-content: end;
}
.cover-container {
position: absolute;
display: grid;
place-content: center;
height: 400px;
width: 900px;
z-index: 999;
margin-left: 300px;
background-color: bisque;
overflow: hidden;
}
.image-container{
position: relative;
display: flex;
width: 75%;
height: 400px;
}
img{
animation: slide 7.5s linear infinite;
}
#keyframes slide {
0% {
transform: translate(0);
}
100% {
transform: translateX(-600%);
}
}
<div class="container">
<div class="main-container">
<div class="cover-container"></div>
<div class="image-container">
<img src="https://source.unsplash.com/random/300x400" alt="" />
<img src="https://source.unsplash.com/random/300x400" alt="" />
<img src="https://source.unsplash.com/random/300x400" alt="" />
<img src="https://source.unsplash.com/random/300x400" alt="" />
<img src="https://source.unsplash.com/random/300x400" alt="" />
</div>
</div>
</div>

Set an image inside CSS spinner and want it to resize it.image should be in static

I am working on an angular application and implemented spinner using CSS.
Now the spinner working as expected.
I have added a background image inside the CSS using background-image:url()
Here, the problem is image also rotate with the spinner.
Here is my CSS
#spinner {
-webkit-animation: frames 1s infinite linear;
animation: frames 1s infinite linear;
background: transparent;
border: .3vw solid #FFF;
border-radius: 100%;
border-top-color: #250463;
background-image:url("../../../../assets/images/svg/img.svg") ;
width: 5vw;
height: 5vw;
opacity: .6;
padding: 0;
position: absolute;
z-index: 999;
justify-content: center;
align-items: center;
}
#keyframes frames {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
.spinner-wrapper {
position: fixed;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.3);
z-index: 998;
}
html code
<div *ngIf="isLoading" class="spinner-wrapper">
<div fxLayoutAlign="center center" id="spinner">
</div>
</div>
Experiment 1
added another style img
img {
max-width: 5vw;
position: absolute;
max-height: 5vw;
top: 0;
height: 5vw;
width: 5vw;
clip-path: circle(45% at 50% 49%);
}
i have updated my html code as well
<div *ngIf="isLoading" class="spinner-wrapper">
<div fxLayoutAlign="center center" id="spinner">
</div>
<img src="">
</div>
Experiment 2
added background-attachment: fixed; inside spinner.Still the image is rotating
**Experiment 3 **
I made below changes.now its working
added new css
z-index: 8;
justify-content: center;
top:230px;
left: 575px;
.img {
position: absolute;
top: 0;
width: 42px;
height: 48px;
}
html changes
<div *ngIf="isLoading" class="spinner-wrapper">
<div fxLayoutAlign="center center" id="spinner">
</div>
<img src="../../../../assets/images/svg/img.svg">
</div>
One draw back is here.if i change the screen size,spinner and image appears different position
how can i solve this
Now the image showing some where else in the UI.
how can i include image inside the spinner.
How can i stop spinning my image?
Can we set image size
This is my first experience on CSS.If anything wrong please correct me.

Change divs as page scrolls

I'm trying to do something like this demo. As the page scrolls down, the various parts become visible. I added a jsfiddle here. As you can see, when the second line of text is hovered it overwrites the line above it. I know my code is using hover and the demo site changes with scrolling but I thought this would be easier to get to work first.
Would someone please explain how do I make it so only the contents of the div with ID changeme is enlarged without affecting the others? Here's my code:
<style>
#changeme {
height: 50px;
width:100px;
transition: all .5s ease-in-out;
}
#changeme:hover {
height: 200px;
width:100px;
transform: scale(1.5);
}
</style>
<div>
<h1>Title</h1>
<div>
<div>Main text<div>
<div id="changeme">
<div>Some Text</div>
<div><img src="example.png"></div>
</div>
</div>
</div>
Run this in full-page mode. Here you go:
var ScrollFunction = function() {
var y = window.scrollY;
var viewport = window.innerWidth;
var counter = (y/viewport) * 100;
if ( counter >= 10) {
document.getElementById("containerOne").className = "container show"
}
if (counter >= 20) {
document.getElementById("containerTwo").className = "container show"
}
if (counter >= 30) {
document.getElementById("containerThree").className = "container show"
}
};
window.addEventListener("scroll", ScrollFunction);
*{
margin: 0;
padding: 0;
box-sizing: border-box;
color: #fff;
}
body{
height: 200vh;
background-color: #313131;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.container{
width: 80%;
height: 500px;
border: 1px solid rgb(126, 126, 126);
margin-bottom: 5vh;
display: none;
justify-content: center;
align-items: center;
flex-direction: row;
}
.box{
width: calc(80%/4);
display: flex;
height: 50%;
opacity: 1;
margin-left: 10px;
justify-content: center;
align-items: center;
background-color: rgba(255, 255, 255, 0.185);
animation: 1s 1 linear normal showUp;
transition: .4s all;
}
.box:first-child{
margin: 0;
}
.box:hover{
transform: scale(1.5);
}
.show{
display:flex;
}
#keyframes showUp {
0%{
height: 0;
opacity: 0;
display: none;
}
100%{
display: flex;
height: 50%;
opacity: 1;
}
}
<div id="containerOne" class="container">
<div class="box">MyBox1</div>
<div class="box">MyBox2</div>
<div class="box">MyBox3</div>
<div class="box">MyBox4</div>
</div>
<div id="containerTwo" class="container">
<div class="box">MyBox1</div>
<div class="box">MyBox2</div>
<div class="box">MyBox3</div>
<div class="box">MyBox4</div>
</div>
<div id="containerThree" class="container">
<div class="box">MyBox1</div>
<div class="box">MyBox2</div>
<div class="box">MyBox3</div>
<div class="box">MyBox4</div>
</div>
If you want to change the size of an element on hover without affecting others then you can use just the transform: scale.
If you also (or instead of) alter the width and/or height then unless the element is positioned in some non-relative way it will 'disturb' elements around it.
So try:
#changeme:hover {
transform: scale(1.5);
}
When you come to want to expand elements as they come into view, investigate IntersectionObserver. You can attach an observer to each of those elements and as they appear you can transform them, or use CSS animate and/or a delay setting to get the sort of effects shown in the linked site.

Get stacked divs to stick to the bottom with CSS Grid

In the following layout, I'm trying to get my content, when hovered over, to stay bottom-aligned in the overall box, so that the words "HEADLINE" and "Subhead" stay where they are and the revealed <ul> just "sits on top" of it. I'm wrapping my head around CSS Grid as best I can - but I am at a loss.
.programbox {
display: grid;
grid-template-areas: 'item';
align-content: end;
justify-content: stretch;
height: 300px;
width: 700px;
background-image: url(https://heroshockey.com/wp2021/wp-content/uploads/2021/07/program-billboards-future-stars.jpg);
background-size: cover;
background-position: 50%;
background-repeat: no-repeat;
}
.programbox::before {
content: '';
grid-area: item;
background-color: red;
mix-blend-mode: multiply;
}
.content {
grid-area: item;
isolation: isolate;
color: white;
align-self: end;
}
.details {
display: none;
}
h1,
p {
margin: 0;
padding: 10px;
}
.programbox:hover .content {
height: 300px;
}
.programbox:hover .details {
display: inherit;
}
<div class="programbox">
<div class="content">
<div class="details">
<ul>
<li>Grades 4 – 8, participants referred by partner schools or social services agencies</li>
<li>Weekly on-ice practices</li>
<li>Learn on-ice skills, confidence building, equipment care</li>
<li>Intro to mentoring relationships with volunteers & HEROS All Stars</li>
</ul>
</div>
<h1 class="header">HEADLINE</h1>
<div class="description">
<p>Subhead</p>
</div>
</div>
</div>
(I do want the .content box to be full height of the container on rollover, turning the entire image red.)
Additionally... I can't get the hover transition to go slower with "transition: 1s;" regardless of which element I place that rule on.
Thanks for any help or suggestions!
I tried your code snippet and i did refactor it. Removed unnecessary html tags and changed some style options.
.programbox {
height: 300px;
width: 700px;
background-image: url(https://heroshockey.com/wp2021/wp-content/uploads/2021/07/program-billboards-future-stars.jpg);
background-size: cover;
background-position: 50%;
background-repeat: no-repeat;
position: relative;
overflow: hidden;
}
.programbox::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: red;
mix-blend-mode: multiply;
transition: all 1s ease-in-out;
transform: translateY(73%);
}
.programbox:hover::before {
transform: translateY(0%);
}
.content {
height: 100%;
display: grid;
grid-template-rows: 1fr repeat(2, 35px);
overflow: hidden;
isolation: isolate;
color: white;
}
h1,
p,
li {
line-height: 1;
}
.header {
grid-row: 2;
}
.description {
grid-row: 3;
}
.details {
grid-row: 1;
}
.header,
.description {
margin: 0;
padding: 0 10px;
align-self: flex-start;
}
.details {
transform: translateY(100px);
opacity: 0;
user-select: none;
transition: all 0.5s ease-in-out;
}
.programbox:hover .details {
transform: translateY(0);
opacity: 1;
user-select: auto;
transition: all 1.5s ease-in-out;
}
<div class="programbox">
<div class="content">
<h1 class="header">HEADLINE</h1>
<p class="description">Subhead</p>
<ul class="details">
<li>
Grades 4 – 8, participants referred by partner schools or social
services agencies
</li>
<li>Weekly on-ice practices</li>
<li>Learn on-ice skills, confidence building, equipment care</li>
<li>
Intro to mentoring relationships with volunteers HEROS All Stars
</li>
</ul>
</div>
</div>

Why is there a border around modal box header?

Appears in latest version of chrome - am I missing something? I can't see a reason for this border; it appears above, to the left, and most prominently to the right of the element:
Fiddle
.header {
width: 100%;
background-color: #FFBF76;
text-align: center;
outline: none;
}
.modal {
position: absolute;
left: 50%;
top: 50%;
transform-style: preserve-3d;
transform: translate(-50%, -50%) translate3d(0, 0, 0);
border: 3px solid #FFBF76;
background: #FFF1BD;
overflow: auto;
border-radius: 0px;
outline: none;
}
.modalBackground {
position: fixed;
inset: 0px;
background-color: #00000066;
}
<div class="modalBackground">
<div class="modal">
<div class="header">
My Header
</div>
<div>
some content
</div>
</div>
</div>
Edit
Tried applying both suggestions, to limited success. Even with the new flex based approach (fiddle) the result is the same.
You have some invalid / unnecessary properties set leaving it to interpretation by the browsers which could render different accordingly like for example border-radius would be 0 instead of with px, inset wouldn't apply to a fixed position element, and a hex color is only 6 digits (if you want an alpha channel for opacity go with rgba instead) etc.
Anyway, made some edits to your example, you should no longer see the issue, hope it helps. Cheers!
.header {
background-color: #FFBF76;
text-align: center;
margin: -1px; /* ensure no resize space */
}
.modal {
border: 3px solid #FFBF76;
background: #FFF1BD;
}
.modalBackground {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: #000066;
}
<div class="modalBackground">
<div class="modal">
<div class="header">
My Header
</div>
<div>
some content
</div>
</div>
</div>
<!-- <asd></asd> = not a valid element -->
The issue is the transform: translate(-50%,-50%) translate3d(0,0,0); on the modal class. Why not use a flex display for your modal? You would not have to rely on positioning and transform hacks to get the element centered.
body {
margin: auto;
}
.header {
width: 100%; /* <-- removed, already a block level element */
background-color: #FFBF76;
text-align: center;
outline: none;
}
.modal {
/* position: absolute; <-- removed */
/* left: 50%; <-- removed */
/* top: 50%; <-- removed */
/* transform-style: preserve-3d; <-- removed */
/* transform: translate(-50%,-50%) translate3d(0,0,0); <-- removed */
border: 3px solid #FFBF76;
background: #FFF1BD;
overflow: auto;
/* border-radius: 0px; <-- no need to specify 0px, is by default */
outline: none;
}
.modalBackground {
/* position: fixed; <-- removed */
display: flex; /* <-- added */
justify-content: center; /* <-- added */
align-items: center; /* <-- added */
width: 100vw; /* <-- added */
height: 100vh; /* <-- added */
/* inset: 0px; <-- removed */
background-color: rgba(0, 0, 0, 0.4) /* typo? #00000066*/
}
<div class="modalBackground">
<div class="modal">
<div class="header">
My Header
</div>
<div>
some content
</div>
</div>
</div>

Resources