How to stop the jumping jack of text change in React - reactjs

How to smoothly transition from text to svg in react.
As soon as I click on next button shown in pic as ">" ,the text changes to svg.But there is some sort of jumping due to change in overall height.
How can I smoothly transition between two.
Note: Unfortunately, I can't share the code as this is not a personal
project.

You can set the height of the containing element to the heighest element. Therefore you need to place them in a row with a negative margin-right so that they overlay each other. Only the element that you make visible will be shown when you hide the other elements with visibility: hidden;
Here is an example:
var elements = document.querySelectorAll('.block__element');
document.querySelector('button').addEventListener('click', () => {
elements.forEach(element => {
if(element.classList.contains('block__element--visible')) {
element.classList.remove('block__element--visible');
} else {
element.classList.add('block__element--visible');
}
})
});
.block {
background: #aaa;
display: flex;
}
.block__element {
width: 100%;
margin-right: -100%;
visibility: hidden;
opacity: 0;
transition: visibility 1s, opacity 1s;
}
.block__element--visible {
visibility: visible;
opacity: 1;
}
<div class="block">
<div class="block__element block__element--visible">
<div style="background: #f00">Content 1</div>
</div>
<div class="block__element">
<div style="height: 200px; background: #0f0">Longer content 2</div>
</div>
</div>
<button>Toggle between elements</button>

Related

How do I use animation that spreads up and down when I make a drop-down menu?

I'm making a drop-down menu now. When I put my mouse on a specific part, the drop-down menu opens and when the mouse goes out of the browser, I want to make the drop-down menu disappear. I made a state value called isMouseOver to return true when the mouse goes up and to use jquery to return false when the mouse goes out of the browser. When the mouse goes up, I used animation to implement it as I wanted, but I want to implement animation that slowly disappears up when the mouse goes out of the browser, but this part doesn't work well. I put this part in an animation as well, but the animation overlapped and it was executed strangely. To sum up the question, how do I put the animation when isMouseOver becomes false and the display becomes none?
import { useState } from 'react';
import styled, {keyframes} from 'styled-components';
import $ from 'jquery';
// animation when mouseover
const dropdownAnimation = keyframes`
0% {
transform: translateY(-30%);
}
100% {
transform: translateY(0);
}
`
function HeaderRight () {
// Check mouseover
const [isMouseOver, setIsMouseOver] = useState(false)
// return true when mouse over
const ActMouseOver = () => {
setIsMouseOver(true)
}
// return false when mouse over
const ActMouseLeave = () => {
setIsMouseOver(false)
}
// return false when the mouse is out of the browser
$(document).mouseleave(function () {
ActMouseLeave();
});
return (
<HeaderRightWrap isMouseOver={isMouseOver} onMouseEnter={ActMouseOver}>
<ul className='HeaderRightWrapUl'>
<li className='HeaderRightWrapUlLi'>
<ul className='HeaderRightWrapUlLiUl'>
<li className='HeaderRightWrapUlLiUlLi'>
Hello
</li>
</ul>
</li>
</ul>
</HeaderRightWrap>
)
}
export default HeaderRight;
const HeaderRightWrap = styled.div`
position: relative;
box-sizing: border-box;
bottom: 40px;
.HeaderRightWrapUl {
height: 100%;
margin: 0 auto;
padding: 0;
list-style: none;
box-sizing: border-box;
display: block;
margin-inline-end: 0px;
margin-inline-start: 0px;
margin-block-start: 1em;
margin-block-end: 1em;
padding-inline-start: 40px;
}
.HeaderRightWrapUlLi {
z-index: 1000;
position: relative;
float: left;
width: auto;
height: 100%;
padding-right: 80px;
transition: padding .3s;
}
.HeaderRightWrapUlLiUl {
display: ${props=>props.isMouseOver===true?'auto':'none'};
position: absolute;
animation: ${dropdownAnimation} 0.3s ease;
}
.HeaderRightWrapUlLiUlLi {
margin-top: 0;
}
`

Click event produces different transition delays, despite equal values

I am creating a simple Dropdown menu in React. The initial event of the drop down works as expected. However, when retracting the dropdown there is a noticeable delay in the transition despite equal default values.
The CSS transition properties are identical so I am not sure why there is a delay. I have also set the transition delay value of both explicitly to 0, to be sure.
here is the component
class DrawerLink extends React.Component {
constructor() {
super();
this.state = { collapse: false };
this.handleLinkToggle = this.handleLinkToggle.bind(this);
}
handleLinkToggle(e) {
this.setState({ collapse: !this.state.collapse });
}
render() {
const { collapse } = this.state;
return (
<div className="DrawerLinkContainer">
<div onClick={this.handleLinkToggle}>
<div className="image-container">
<img src="../public/images/user.jpeg" />
</div>
<p>Steave Jobs</p>
</div>
<div
className={
collapse ? "sub-menu-container collapse" : "sub-menu-container"
}
>
<p>First Sub Menu</p>
<p>Second Sub Menu</p>
</div>
</div>
);
}
}
and the CSS:
.sub-menu-container {
padding-left: 40px;
max-height: 0px;
overflow: hidden;
transition: max-height 1s linear 0s;
&.collapse {
max-height: 500px;
transition: max-height 1s linear 0s;
}
p {
padding: 7px 35px 7px 15px;
}
}
Because you have set max-height to 500px and your content is only about 60px, the first transition is still executing causing what seems like a delay. I.E increasing to a "max height" of 500px.
You can see better if you set a background colour on the sub container and set the height equal to the max height in the collapse class. Something like:
.sub-menu-container {
padding-left: 40px;
max-height: 500px;
overflow: hidden;
transition: max-height 1s linear 0s;
background: red;
&.collapse {
max-height: 0px;
}
p {
padding: 7px 35px 7px 15px;
}
}
The real solution is to use an animation library because transitions have issues (they just don't work) when element are removed from the DOM by React.
If you need a solution to your example, you need to know the height of the sub container and use that as a max height. It's not very dynamic though.

angular ng-class appending classes does not trigger css3 transition

I have created custom modal directive in angular but it seems transition is not working and i can't figure out why.
Inside my directive isolated scope i have method toggleModal() which is switching modalState to true / false. So everything is basically working except animation
HTML:
<span class="glyphicon glyphicon-edit" ng-click="toggleModal()"></span>
<div class="annotation-panel"
ng-class="{'annotation-panel-active' : modalState == true, 'annotation-panel-inactive' : modalState == false}">
<div class="annotation-modal" ng-class="{'active':modalState == true, 'inactive':modalState == false}">
<button type="button" class="btn btn-default" ng-click="toggleModal()">Close</button>
</div>
</div>
CSS:
.annotation-panel{
display: none;
position: fixed;
top:0;
left:0;
z-index: 1000;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
}
.annotation-panel-active{
display: block!important;
}
.annotation-panel-inactive{
display: none!important;
}
.annotation-modal{
position: fixed;
z-index: 1001;
left:10vw;
top: 0;
width: 80vw;
height: auto;
overflow-y: scroll;
opacity: 0;
background-color: whitesmoke;
transition: all 0.5s linear;
}
.annotation-modal.active{
top: 10vh;
opacity: 1;
}
.annotation-modal.inactive{
top: 0;
opacity: 0;
}
So basically using ng-class im switching between two classes
.active and .inactive but it seems transition does not animate the change in the classes, i think i have some general mistake but can't find it. I don't use ngAnimate because i'm making module so i don't a lot of dependencies and that's why i'm making it custom with classes
You are hiding the annotation-panel with display:none instantly when the state changes to inactive, so the contained annotation-modal wont be visible.
The use of ng-animate here would be to only apply ng-hide (and thus, display:none) when the animation has finished.
Without that, you need to use a different method to hide the panel after the animation has finished. Here is one solution with moving the panel offscreen. Notice how the transition-delay in inactive state matches the animation length of the modal fadeout. Also, by only having the transition on the inactive state, when the panel becomes active, it moves instantly to the viewport.
.annotation-panel{
position: fixed;
top: -2000px;
left: 0;
z-index: 1000;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
}
.annotation-panel-active{
top: 0;
}
.annotation-panel-inactive{
transition-property: top;
transition-delay: 0.5s;
transition-duration: 0s;
}
.annotation-panel{
position: fixed;
top: -2000px;
left: 0;
z-index: 1000;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
}
.annotation-panel-active{
top: 0;
}
.annotation-panel-inactive{
transition-property: top;
transition-delay: 0.5s;
transition-duration: 0s;
}
.annotation-modal{
position: fixed;
z-index: 1001;
left:10vw;
top: 0;
width: 80vw;
height: auto;
overflow-y: scroll;
opacity: 0;
background-color: whitesmoke;
transition: all 0.5s linear;
}
.annotation-modal.active{
top: 10vh;
opacity: 1;
}
.annotation-modal.inactive{
top: 0;
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<span class="glyphicon glyphicon-edit" ng-click="modalState =!modalState">click</span>
<div class="annotation-panel"
ng-class="{'annotation-panel-active' : modalState == true, 'annotation-panel-inactive' : modalState == false}">
<div class="annotation-modal" ng-class="{'active':modalState == true, 'inactive':modalState == false}"> helloo
<button type="button" class="btn btn-default" ng-click="modalState = false">Close</button>
</div>
</div>
</div>
You should go for ng-hide if you just have to make display none for the element
here are some animation css for that
//
//a working example can be found at the bottom of this page
//
.my-element.ng-hide-add, .my-element.ng-hide-remove {
/* this is required as of 1.3x to properly
apply all styling in a show/hide animation */
transition: 0s linear all;
}
.my-element.ng-hide-add-active,
.my-element.ng-hide-remove-active {
/* the transition is defined in the active class */
transition: 1s linear all;
}
.my-element.ng-hide-add { ... }
.my-element.ng-hide-add.ng-hide-add-active { ... }
.my-element.ng-hide-remove { ... }
.my-element.ng-hide-remove.ng-hide-remove-active { ... }
Link for more details animations

Re-order containers using media queries

I'm wanting to re-order a number of containers when the webpage is being viewed on a particular device.
I currently have three divs floated left. Two smaller divs either side of a larger div. However, when the media query kicks in a would like the middle of the three to sit above the other two. In theory changing its position from 2nd to 1st.
Is this possible with pure CSS? Or would I need to get jQuery involved? I've set up a test fiddle here for anybody who can help with my initial attempts, but I'm having no joy so far... http://jsfiddle.net/r8qZ2/
Example HTML:
<div class="panels">
<div class="panel-one">Panel 1</div>
<div class="panel-two">Panel 2</div>
<div class="panel-three">Panel 3 </div>
</div>
Example CSS:
.panels {
width: 100%;
max-width: 1280px;
margin: 0 auto;
}
.panel-one, .panel-three {
width: 24.0625%;
height: 400px;
float: left;
background: red;
}
.panel-three {
margin: 0 0 0 1.25%;
}
.panel-two {
width: 49.375%;
height: 400px;
float: left;
margin: 0 0 0 1.25%;
background: blue;
}
#media only screen and (max-width: 800px) {
.panel-one, .panel-three {
width: 49%;
height: 400px;
}
.panel-three {
margin: 0 0 0 2%;
}
.panel-two {
width: 100%;
float: none;
clear: left;
margin: 0;
}
}
Any help would be gratefully received!
Re-order responsive containers with CSS? With float based layouts, no. In cases with just one floated sidebar it's possible, but not with two.
If you adjust your layout not to use floats then it's most certainly possible.
Note: I highly recommend a mobile first-approach to your CSS, using min-width media queries. However since you're using max-width in your example I will also do so in mine:
Using position: absolute:
Place the element you want to be at the top as the first element in your HTML markup, and position the sidebars to the sides with position: absolute. Give the parent element position: relative, and give it a padding value equal to the width of the sidebars.
Then, with media queries, remove the padding and position: absolute you set.
Example:
HTML:
<div class="panels">
<div class="panel-two">Panel 2</div>
<div class="panel-one">Panel 1</div>
<div class="panel-three">Panel 3</div>
</div>
CSS:
.panels {
position: relative;
padding: 0 25%;
}
.panel-one,
.panel-three {
position: absolute;
top: 0;
bottom: 0;
width: 25%;
}
.panel-one { left: 0; }
.panel-three { right: 0; }
#media only screen and (max-width: 800px) {
.panels {
padding: 0;
}
.panel-one,
.panel-three {
position: static;
width: auto;
}
}
Here's a pen with your markup adjusted to this.
A major drawback to this is that the sidebars are taken out of the content flow with position: absolute, so depending on your layout this may not be a possible solution.

bootstrap 3.0 full length body sidebar

I'm trying to get bootstrap divs to be full body length.
This is what I've tried so far: http://jsfiddle.net/bKsad/315/
html, body {
min-height: 100%
}
.wrap {
height: 100%
}
.sidebar {
background-color:#eee;
background-repeat: repeat;
padding:0;
min-height:100% !important;
position:relative;
}
.sidebar .sidebar-content {
height:100%;
width:100%;
padding: 5px;
margin:0;
position:relative;
}
As the right column grows longer, I want the sidebar to do the same.
The key is to understand the "col-md-x" and "col-md-offset-x" styles provided by Bootstrap 3:
<div class="container-fluid">
<div class="row">
<div class="col-md-3 sidebar">
Sidebar Content
</div>
<div class="col-md-9 col-md-offset-3 content">
Main Content
</div>
</div>
</div>
Then use CSS to make sure the breakpoints line-up. You'll need to fine-tune padding/margin for your particular needs, but the offset and #media breakpoints handle the overall layout pretty well:
html, body, .container-fluid, .row {
height: 100%;
}
.sidebar {
background-color: #CCCCCC;
}
#media (min-width: 992px) {
.sidebar {
position: fixed;
top: 0;
left: 0;
bottom: 0;
z-index: 1000;
display: block;
background-color: #CCCCCC;
}
}
Working solution: http://www.bootply.com/111837
If you use "col-sm-x" or "col-lg-x" you just change the #media CSS to the corresponding min-width (768px for sm and 1200px for lg). Bootstrap handles the rest.
I solved this by using an absolutely positioned div and a bit of jQuery. I have a Bootstrap navbar with a fixed height of 50px, so that is why you're seeing the 50's in the code. You can remove this if you don't have a top navbar.
This solution works dynamically with any height.
The CSS:
.sidebar {
background-color: #333333;
position: absolute;
min-height: calc(100% - 50px);
}
The jQuery:
var document_height = $(document).height();
var sidebar = $('.sidebar');
var sidebar_height = sidebar.height();
if (document_height > sidebar_height) {
sidebar.css('height', document_height - 50);
}
The neat thing about this is there will be no flickering of the background because its using CSS to adjust the min-height, so that the jQuery resizing that normally causes a flickering of the background will be hidden on page load.
approach 1: added empty div with style="clear:both" at the end of wrap div.
http://jsfiddle.net/34Fc5/1/
approch 2: http://jsfiddle.net/34Fc5/ :
html, body {
height: 100%;
}
.wrap {
height: 100%;
overflow: hidden;
}
.sidebar {
background-color:#eee;
background-repeat: repeat;
padding:0;
height:100% !important;
position:relative;
}
.sidebar .sidebar-content {
height:100%;
width:100%;
padding: 5px;
margin:0;
position:relative;
}
added "overflow: hidden;" to .wrap
changed height: 100% to html, body
changed height: 100% to .sidebar
using css way, the height of the sidebar will only match the view port of the browser. so if you look at approach 1, when you scroll you will notice the background stop at viewport. to fix it js is required.
The only thing that got it working for me (after many hours of trying everything) was
HTML
<nav class="col-sm-3 sidebar">
CSS
padding-bottom: 100%;
The padding in percent did it for me. Now it goes all the way to the bottom of the page.

Resources