I am currently working on a website of my own and I'm trying to implement a cool animation on page load, where the navbar fades in, and the center image both fades in and rises up to where it is supposed to be on the page.
I got both of these transitions implemented easily, but the only problem is that when the center image animation acts on the page, it pulls the entire page down, I attached a little clip of it happening on my site to this post.
I would like it so that when the page loads, the animation does not move the entire page down with it, and instead the scroll wheel is at the top at the end of the animation.
My react component:
`
import React from "react";
import tenGreenLogo from "../images/10Green Logo Black (1).png";
import "./HomeContent.css";`
function HomeContent() {
return (
<>
<div className="center-div">
<img src={tenGreenLogo}></img>
</div>
<div className="globe-div">
<div className="globe"></div>
</div>
</>
);
}
export default HomeContent;
`
and my CSS:
`
.center-div {
display: flex;
justify-content: center;
align-items: center;
padding-top: 7rem;
padding-bottom: 7rem;
}
.center-div img {
width: 40rem;
animation: transitionIn 1s;
}
.globe-div {
display: flex;
justify-content: center;
align-items: flex-start;
width: 100%;
padding-bottom: 5rem;
padding-top: 5rem;
}
.globe {
border-radius: 50%;
width: 100rem;
height: 100rem;
background-color: #67cfcf;
display: inline-block;
}
#keyframes transitionIn {
from {
opacity: 0;
transform: translateY(4rem);
}
to {
opacity: 1;
transform: translateY(0rem);
}
}
`
Does anybody know what could be happening here?
I have tried putting the animation property both on the image itself as well as the div it is nested in, but neither of those appear to solve the problem. I am hoping that I can make it so the page does not get pulled down when the animation loads.
Related
How is it possible to make this transition in css the last transition of this gif: https://cdn.dribbble.com/users/757683/screenshots/4317968/dribbble_spec_1_v4.gif
The last one, I put a image here:
Start showing pyramid gradually, and slide it to right releasing the login details on the left.
You can do something like:
The whole parent div shall be bigger than 100vw e.g: 120vw.
The body shall have overflow-x: hidden,
The img should be 100vw while the sign-in part a bit smaller eg: 20vw,
The parent div should be translated in such a way that the img is only visible at the beginning, then we would animate the parent div to be translated to show the sign-in part as well.
Enough of theory, understand from the code below:
* {
margin: 0;
padding: 0;
}
body {
overflow-x: hidden;
}
.parent_container {
display: flex;
width: 120vw;
animation: anime 2s;
}
#keyframes anime {
0% {
transform: translate(-20vw);
}
100% {
transform: translate(0);
}
}
.sign_in_eg {
height: 100vh;
width: 20vw;
background: red;
}
.img_eg {
height: 100vh;
width: 100vw;
background: blue;
}
<div class="parent_container">
<div class="sign_in_eg">This is for signin</div>
<div class="img_eg">This is for image</div>
</div>
I've been building this page using scroll-snap and it's working well on Firefox desktop & mobile, as well as Chrome mobile.
But on Chrome desktop (Edge desktop as well) I get very choppy/laggy scroll animation, to the point I don't consider it usable as it is.
I've been looking for a few hours now, to no avail. Any help or lead or idea would be greatly appreciated.
I'm on Windows 10.
Here's the SCSS for the snap container and items:
.works {
margin: 0;
padding: 0;
scroll-snap-type: y mandatory;
scroll-behavior: smooth;
overflow: scroll;
height: calc(100vh - var(--header-height) - 2vh);
width: 100vw;
position: absolute;
top: calc(var(--header-height) + 2vh);
> div {
margin: 0 auto;
padding: 2vh 0 0;
display: block;
width: clamp(200px, 100vw, 1280px);
min-height: 100%;
z-index: -1;
background-origin: border-box;
background-repeat: no-repeat;
background-attachment: fixed;
background-position: center;
background-size: auto 100%;
border-radius: .5em;
border: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
display: grid;
grid-template-rows: auto 7rem auto;
scroll-snap-align: start;
scroll-snap-stop: always;
}
}
And the matching React component:
function Works() {
const contents = worksContents.map( ({ title, year, text, pic }, i) => {
const styles = {
backgroundImage: `linear-gradient(transparent, #fdfdfd 75%), url(${pic})`,
}
return (
<div key={ i } style={ styles }>
<span className='title'> { title } </span>
<span className='year'> { year } </span>
{ text }
</div> )
}
)
return (
<section className="works">
{ contents }
</section>
)
}
export default Works
I just wanted to second this question as its affecting me too. Scroll-Snap seems to be completely unusable in desktop chrome at the moment.
I made a codepen to demonstrate the problem:
https://codepen.io/lumakker/pen/poaybJd
html:
<div class="testdiv" style="background-color:white">
<p>compare between scrolling with mousewheel and scrolling with autoscroll (middle mouse button click). Mousewheell scroll-snap is very choppy on chrome desktop.</p>
</div>
<div class="testdiv" style="background-color:black"></div>
<div class="testdiv" style="background-color:green"></div>
<div class="testdiv" style="background-color:red"></div>
css:
html {
scroll-snap-type: y mandatory;
height: 100%
}
body {
height: 100%
}
.testdiv {
height: 100%;
scroll-snap-align: start;
}
I hope someone has a solution because I would really like to avoid using a custom scroll-snap js for my website.
When applying a CSS transform based on a hover for my element which contains a title a summary and some other elements, all the children elements would move a second time when I hover over them inside the element.
Basically, the parent and its children(title, highlight...) will be animated a first time when I hover over it. (this is the intended behaviour).
But, if I hover over the title, it will apply the animation to the title individually, a second time. So, the title would be transformed a first time, let's say going up by 10px, and when I hover over it, it will go up again by 10 other pixels. The outer div (parent) will move only once. (Unwanted)
It is like I have applied their own animations to the parent and each one of the children.
I tried to apply transform: none; to all the children elements, but, it does not help in my case.
CSS:
.badge {
flex-basis: 50%;
transform: translateY(0);
transition-duration: 1s;
transition-property: transform;
transition-timing-function: ease-out;
transition-delay: 1s;
backface-visibility: hidden;
}
.badge:last-child {
flex-basis: 100%;
}
.badge :hover {
transform: translateY(-8px);
}
.badge__badge {
margin-bottom: 40px;
margin-right: 40px;
width: 99%;
height: 200px;
background-color: rgb(27, 139, 45);
border-radius: 8px;
color: aliceblue;
box-shadow: 0 4px 2px -2px rgba(0,0,0,0.4);
}
.badge__prime {
margin-left: 20px;
margin-right: auto;
}
.badge__content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
}
.badge__icon {
width: 40px;
height: auto;
margin: 10px;
}
.badge__highlight {
margin-right: auto;
margin-left: 30px;
display: flex;
flex-direction: column;
}
JSX (React):
<div className="badge">
<div className="badge__badge"
style={{ backgroundColor: this.props.backgroundColor }}>
<div className="badge__content">
{this.props.prime ? <h4 className="badge__prime">PRIME</h4>
: <h4 className="badge__prime">Free</h4>}
<h2 className="badge__title">{this.props.titleBadge}</h2>
<div className="badge__highlight">
{this.props.highlightBadge.split('\n').map((i, key) => {
return <div key={key}>{i}</div>;
})}
</div>
</div>
<img className="badge__icon"alt="" src={this.props.iconBadge} />
</div>
</div>
Expected results: the parent div and all its children will animate once on hover and will come back to their state once the mouse is outside of the div.
Actual results: The parent div and all its children animate once on hover, and the children will animate again if the mouse is over one of them.
Link to a jsfiddle that shows my issue
I made modal in React and it's working fine, but I really want to add one small feature. When I'm clicking on button, class of modal is changing and modal is becoming visible, but this happens immediately and I want to add some transition.
My code:
In parent method toggling class and passing props:
toggleModal() {
this.setState({ visibleModal: !this.state.visibleModal });
}
<RegisterModal
visible={this.state.visibleModal}
toggleModal={this.toggleModal}
/>
Children component:
<div className={`modal ${props.visible ? 'modal--visible' : 'modal--invisible'}`}>
My CSS:
.modal {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
justify-content: center;
}
.modal--invisible {
display: none;
}
.modal--visible {
display: flex;
}
Can someone help me?
Possibly related
The display property can't change smoothly, it only has fixed values. It jumps instantly from one to the next. You need to use transition and something like opacity to get a nice fade in.
.modal {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
justify-content: center;
transition: opacity .5s; /* Opacity will fade smoothly */
}
.modal--invisible {
opacity: 0;
pointer-events: none; /* Makes the modal unclickable */
}
.modal--visible {
opacity: 1; /* Modal is visible */
pointer-events: initial; /* Modal is clickable */
}
I read an interesting article the other day and I've been trying to apply it in my workflow.
https://blog.gyrosco.pe/smooth-css-animations-7d8ffc2c1d29#.5a2q978fv
One of the concepts that are mentioned is the idea of only animating elements with opacity and transform. I've been implementing this idea over the last few days and find it pretty awesome.
One issue I've come across is if an element is at opacity 0 the containing parent will still apply the space of the child element. I tried to remove the space with scaling the child element to almost nothing but the space is still persistent.
I was curious if anyone has worked in this manner and has advice on how to animate a parent element to grow with the child element?
function showHiddenBox() {
let hiddenBox = document.querySelector('.hiddenbox')
hiddenBox.setAttribute('data-state', hiddenBox.getAttribute('data-state') === 'hidden' ? 'visible' : 'hidden');
}
.parentbox {
width: 200px;
background-color: #564d49;
}
.showingbox {
display: flex;
align-content: flex-start;
align-items: center;
justify-content: center;
width: 100%;
height: 100px;
background-color: #63cdff;
}
.hiddenbox {
width: 100%;
height: 100px;
transition: all 1s;
background-color: pink;
}
.hiddenbox[data-state="hidden"] {
opacity: 0;
transform: scaleY(.1) translateY(-50px);
transform-origin: top;
}
.hiddenbox[data-state="visible"] {
opacity: 1;
}
<div class="parentbox">
<div class="showingbox">
<button onclick="showHiddenBox()">Click Me</button>
</div>
<div class="hiddenbox" data-state="hidden"></div>
</div>
To further explain myself I've created this snippet. I want to create an animation with just opacity and transform where the brown of the parent element doesn't show but the parent will expand when the child is created.
function showHiddenBox() {
let hiddenBox = document.querySelector('.hiddenbox')
hiddenBox.setAttribute('data-state', hiddenBox.getAttribute('data-state') === 'hidden' ? 'visible' : 'hidden');
}
.parentbox {
width: 200px;
background-color: #564d49;
}
.showingbox {
display: flex;
align-content: flex-start;
align-items: center;
justify-content: center;
width: 100%;
height: 100px;
background-color: #63cdff;
}
.hiddenbox {
width: 100%;
height: 100px;
transition: all 1s;
background-color: pink;
}
.hiddenbox[data-state="hidden"] {
max-height: 0;
transform: scaleY(.1) translateY(-50px);
transform-origin: top;
}
.hiddenbox[data-state="visible"] {
max-height: 300px;
}
<div class="parentbox">
<div class="showingbox">
<button onclick="showHiddenBox()">Click Me</button>
</div>
<div class="hiddenbox" data-state="hidden"></div>
</div>
Use max-height instead of opacity. Over exaggerate the max-height. Depends on how it will work for you. Is this what you want?