css transform stutters in chrome - html

Using transform on two elements works fine in IE and Firefox but somehow "stutters" in Chrome.
I've captured the different behaviours with some gifs:
Firefox
IE
Chrome (notice how the right border "jumps" around")
Example on jsfiddle
Is it possible to fix this behaviour in Chrome? I couldn't find anything when I searched.
Thanks for your help in advance :)
Here is some exemplary code.
HTML:
<div class="outer">
<div class="menu">
asdf
</div>
<div class="content">
<button id="trigger">toggle menu</button>
</div>
</div>
CSS:
.outer > div {
transition: transform 500ms ease, margin-right 500ms ease;
}
.menu {
background-color: #1d1f20;
top: 0;
left: -200px;
width: 200px;
position: fixed;
transform: translate(200px,0);
}
.content {
transform: translate(200px, 0px);
margin-right: 200px;
background: green;
}
JS:
var current = '200px';
$('#trigger').on('click', function() {
current = current === '200px' ? '0' : '200px';
$('.menu').css({transform: 'translate('+current+', 0)'});
$('.content').css({transform: 'translate('+current+', 0)', marginRight: current === '200px' ? '200px' : '0'});
});

Related

CSS Animation from right to left dynamically

The problem I'm facing is:
I have a animated text which goes from right to left, this text change depending on the languague set, what is causing that the total width of the text changes too.
In this picture, the effect I want is working fine, because some properties are fixed.
Now, when I change for a longer text the problem cames up.
So, this is what I have now:
And this is what I'd like to have:
Here is the code I'm using:
ReactJS Side:
constructor(props) {
super(props);
this.state = {
checked: false
}
}
componentDidMount() {
window.addEventListener('scroll', () => {
if (event.srcElement.body.scrollTop >= 1400) {
this.setState({ checked: true });
}
});
}
render() {
return (
<div>
... stuff
<span style={{ fontSize: "40px", color: this.state.theme.COLOR_3 }}>
<input type="checkbox" id="Resume-chk" style={{ display: "none" }} checked={this.state.checked} />
<b id="Resume-title">{this.state.languageSet.RESUME}</b>
</span>
... more stuff
<div>
);
}
CSS Side:
//This is the text
#Resume-title {
display: inline-block;
-webkit-transition: color 200ms ease-in;
-moz-transition: color 200ms ease-in;
transition: color 200ms ease-in;
-webkit-transition: right 500ms ease-in;
-moz-transition: right 500ms ease-in;
transition: right 500ms ease-in;
position: relative;
right: -40.5%;
}
//This is the text when the checkbox is checked
#Resume-chk:checked ~ #Resume-title {
right: 40.5%;
}
So, the question is: How to fix it? Or maybe there is some concept I'm missing and it is a little bit more than just fixing a bug.
Also I'm not sure if doing things like right: -40.5%; and right: 40.5%; is a good practice, but I cant find a way to animate property like float or align.
Of course, if there is a way to fix it, but also there is a way to do it even better, It is also welcome!!!
EDITED: here the fiddle containing the whole html section, copied from dev console
You need a combination of positioning with right and a transform.
This is an usual idea for centering an element, adapted to your request:
.container {
width: 300px;
background-color: lime;
margin: 10px;
position: relative;
}
.item {
display: inline-block;
position: relative;
right: -100%;
transform: translateX(-100%);
transition: right 1s, transform 1s;
}
.container:hover .item {
right: 0%;
transform: translateX(0%);
}
<div class="container">
<div class="item">Item</div>
</div>
<div class="container">
<div class="item">Item long</div>
</div><div class="container">
<div class="item">Item longer longer</div>
</div>

CSS-ReactJS Animation when an element gets visible

I don't know if what I want is possible with pure CSS, I'd prefer to avoid using JQuery because I'm building my app with ReacJS.
I have the following effect
.container {
display: flex;
flex-direction: column;
}
#box {
display: inline-block;
width: 100px;
height: 100px;
background-color: red;
transition: all 800ms ease-in;
position: relative;
right: calc(100px - 100%);
}
#chk:checked ~ #box{
right: 0;
}
<div class="container">
<label>check the input to see the effect</label>
<br/>
<input id="chk" type="checkbox">
<div id="box"></div>
</div>
It works when an input (checkbox) is checked, the thing is I want to reproduce the same effect but when an element is shown in the screen.
Why not to use JQuery?
As I'm building my app using ReactJS, using JQuery is not recommended neither the community nor Facebook.
I'd like to use CSS some React component, but I don't know how.
Check my own answer to see how I figured it out
Why don't you create a class instead of selector with checked property and then toggle the class with react.
Using CSS + ReactJS I solved doing this:
I used a checkbox to check or uncheck depending on where the scroll is. Then using CSS just change where the text is being rendered.
CSS Code:
#WhoIAm-title {
display: inline-block;
-webkit-transition: all 800ms ease-in;
-moz-transition: all 800ms ease-in;
transition: all 800ms ease-in;
position: relative;
right: -38%;
}
#WhoIAm-chk:checked ~ #WhoIAm-title {
right: 38%;
}
ReactJS Code:
componentDidMount() {
window.addEventListener('scroll', () => {
if (event.srcElement.body.scrollTop >= 620 && event.srcElement.body.scrollTop <= 650) {
this.setState({ checked: true });
}else if (event.srcElement.body.scrollTop >= 820 || event.srcElement.body.scrollTop <= 600) {
this.setState({ checked: false });
}
});
}
render() {
return (
<div id="whoiam" className="Container column">
<span>
<input type="checkbox" id="WhoIAm-chk" style={{ display: "none" }} checked={this.state.checked} />
<b id="WhoIAm-title">Title to toggle to right</b>
</span>
</div>
);
}

Weird rendering in FF with transition transform

I'm building a header that can be extended when clicking a button. Then additional content should slide in from behind the original header. Both header are positioned fixed as they should scroll with the page. To smoothly animate the slide in/out I'm using CSS with transition on transform.
This works fine in Chrome and IE but fails in FF. In FF the rendering is odd. It looks like the border is drawn onto the new position immediatly, then the header slides in and the border in then finally corrected to the correct position. Same on sliding out.
This happens in FF 39.0 on Windows 7. The same version but on Kubuntu Linux does not show this behaviour. I experienced this as well when using translate3d or top properties as workaround.
HTML:
<header id="header">This is the header</header>
<div id="slider">
<div>Slider content goes here</div>
<button id="trigger" type="button">Toggle</button>
</div>
CSS:
#header, #slider {
display: block;
position: fixed;
top: 0;
width: 100%;
height: 50px;
border-bottom: 1px solid black;
}
#header {
background-color: red;
z-index: 10;
}
#slider {
background-color: green;
-webkit-transition: -webkit-transform .5s;
-moz-transition: -moz-transform .5s;
transition: transform .5s;
z-index: 9;
}
#slider.opened {
-webkit-transform: translateY(50px);
-moz-transform: translateY(50px);
transform: translateY(50px);
}
#trigger {
position: absolute;
height: 25px;
bottom: -25px;
right: 20px;
}
JS:
var opened = false;
document.getElementById("trigger").onclick = function () {
document.getElementById("slider").className = opened ? "" : "opened";
opened = !opened;
};
JSFiddle: https://jsfiddle.net/avwhksbw/
So, what's going on here? Are you able to reproduce this weird animation rendering on FF? What could I do about this? Using CSS animations? JQuery?
EDIT: Here is a screenshot that shows the problem. This is taken when the slider opens. Looks kind of similar when closing.

Have these css collapsable divs open by default?

I'm using
jsfiddle.net/ts4dk6hp/
and wondering if I can
a) have the content open by default
b) have a smooth css transition to open (with no javascript)
HTML
<div id="show">
Open
<div id="content">
Close
<br>some text...
</div>
</div>
CSS
#content {
display: none;
}
#show:target #content {
display: block;
}
#show:target #open {
display: none;
}
Any help would be great thanks!
First, I suggest you use javascript instead of just css. 2nd, I want to you to remember that css animations are only supported by newer browsers.
I have updated your jsfiddle, hopefully it will be helpful for you.
HTML
<div id="show">
Open
<div id="content">
<br>some text...
<br> Mur text, duh...
<br> Lorem
<br> Ipsum
<br> Watchama sayin'?
<br> Have fun!
</div>
CSS
#content {
transition: opacity 1s ease-in, height 500ms ease-out;
opacity: 0;
height: 200px;
width: 200px;
background: gray;
}
JS
var open = true;
$('#openclose').click(function() {
if (!open) {
open = true;
$(this).text('Close');
$('#content').css({
opacity: 1,
height: '200px',
overflow: 'hidden',
});
$('#content').one('transitionend', function() {
$(this).css('overflow', 'auto');
});
} else {
open = false;
$(this).text('Open');
$('#content').css({
opacity: 0,
height: '0px',
overflow: 'hidden',
});
$('#content').one('transitionend', function() {
$(this).css('overflow', 'auto');
});
}
});
http://jsfiddle.net/MashedPotatoes/ts4dk6hp/13/
To expand on humble.rumble.6x3's comment, you cannot do the first OR the second of your requirements without JavaScript. The main reason being that CSS is designed to style the content, not perform animations and interact with events (with exceptions).
Following way you can do using css:
1.) content open by default And smooth css transition to open (with no javascript).
#open {
display: none;
}
#show:target #content {
opacity: 0;
}
#show:target #close {
display: none;
}
#show:target #open {
display: block;
}
#content{
-webkit-transition: opacity 0.5s ease-in-out;
-moz-transition: opacity 0.5s ease-in-out;
transition: opacity 0.5s ease-in-out;
}
#show{
display:table;
}
<div id="show">
<a href="#show" id="close" >Close</a>
<a href="#hide" id="open" >Open</a>
<div id="content">
<br>some text...
</div>
</div>
Hope it helps.

Using css to slide elements when filling empty space

I have several blocks of content. I slide one off to the side, then remove it. Once that is done, I want the blocks below it to slide up and take its place.
JSFiddle Example
HTML
<div id="container">
<div id="elem1" class="item one">
Element 1
</div>
<div id="elem2" class="item two">
Element 2
</div>
<div id="elem3" class="item three">
Element 3
</div>
</div>
CSS
.one {
background-color: red;
}
.two {
background-color: blue;
}
.three {
background-color: green;
}
.item {
height: 150px;
width: 200px;
margin-bottom: 20px;
}
.closed {
-webkit-transition: all .75s ease;
-moz-transition: all .75s ease;
-o-transition: all .75s ease;
transition: all .75s ease;
background-color: yellow;
margin-left: 200px;
opacity: 0;
}
Javascript/JQuery
$('.item').on('click', function(){
$(this)
.addClass('closed')
.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function(){
$(this).remove();
});
});
What transition can I uses so that if I click the red block, once it is removed the blue and green blocks will slide into place?
Working Fiddle
Give a try to this;
$(this).height(0).css({'margin':'0'});
or Probably this;
$(this).css({'margin':'0','height':'0'});
good luck!
You can animate with height and margin equal to 0
$('.item').on('click', function(){
var obj = $(this);
$(this)
.addClass('closed')
.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function(){
obj.animate({ height: 0, margin : 0 }, 0);
});
});
Here is the fiddle link DEMO
You can use .animate() with time and adjust top or margin-top to move the element out of view. Once out you can remove the element and reset the top / margin-top to its original value.