I have this very simple code:
$(document).ready(function() {
$('.content>div').hide();
$('.content>h3').click(function() {
$(this).next().slideToggle('fast');
$(this).toggleClass('active');
});
});
it causes of course that my div slides out from top to bottom. Could you help me add to this code or command the line that in result it will be slide out from right to left??
.slideToggle() animates the height of the matched elements so you will likely have to rely on a different function/method - but this is not that difficult. You can do this either in JavaScript or use CSS3 animation properties. Depends on the use case but I'd probably use the CSS3 option because it is hardware accelerated on most devices so it is smoother.
Here's a simple sketch how that could be done
In the JavaScript file:
$('.content>h3').click(function() {
// just switch the class 'open' the rest is defined in CSS
$(this).next().toggleClass('open');
$(this).toggleClass('active');
});
And in the CSS file:
.content div {
width: 0;
overflow: hidden;
transition: width 1s ease-out;
}
.content div.open {
width: 100%;
}
Example:
http://jsbin.com/qebigohu/2/ (preview)
http://jsbin.com/qebigohu/2/edit (code)
Related
there is an example with content dropdown: https://codesandbox.io/s/expand-content-4pc09c?fil...
But the appearance of content on the button is quite fast. I need to set smoothness using the transition property, but it didn't work.
As far as I understand, you need to add some kind of appearance effect with the help of visability, but here there is a link to useState also tried to set a property for the content: transition: all 0.5s ease-out; but the animation is not happening
I also tried change styles like that:
const styles = {
height: expand ? "auto" : "0px",
maxHeight: expand ? "auto" : "0px",
overflow: expand ? "visible" : "hidden"
};
but it turns out that i have the same result
You have to keep on mind various things to make it works. In your codepen there's a typo in visibility animation in styles.css. I attached you a working snippet but I'm explaining you some important topics about how it works.
Explanation
First of all if you're toggling styles with you styles variable it'll no respect transition as it will be rendered as inline styles, so the approach I use was create a new .wrapper__content.expanded class and the class is the one that'll be toggled with the state.
Second about CSS properties:
visibility cannot be transitioned as it doesn't have 'in-between' values, when the time of the transition (let's suppose 300ms) had passed it will change to visible or hidden with no intermediate values, that's why it cannot be 'animated'. But if you still want to add this property for accessibility purposes you can add a transition-delay to this property timing to trigger the change when height transition had finish.
height property is a difficult one to animate because it needs explicit values to work and I recommend you not to change the height: auto that comes by default, as it'll be adapting to its content (avoiding overflow issues). Instead of transitioning this property you should use max-height in collapsed state with a value of 0 and in expanded state with a value that your content will never reach (1000px in my snippet). This will do the trick, don't forget to add overflow:hidden; to hide the content when it's collapsed.
I think this answer will fulfill you requirements, but any questions feel free to ask. Hope it helps.
const App =() => {
const [expand, setExpand] = React.useState(false);
const onToggle = () => {
setExpand(!expand);
};
return (
<div className="wrapper">
<div className="wrapper__expand">
<button onClick={onToggle} className="wrapper__expand-btn">
+
</button>
Expand
</div>
<div className={expand ? 'wrapper__content expanded' : 'wrapper__content'}>
expanded content
</div>
</div>
);
}
ReactDOM.render( < App / > , document.getElementById("root"));
.App {
font-family: sans-serif;
text-align: center;
}
.wrapper {
display: flex;
flex-direction: column;
}
.wrapper__expand {
display: flex;
column-gap: 10px;
}
.wrapper__content {
margin-top: 10px;
overflow: hidden;
max-height: 0;
transition: max-height .5s ease-in-out;
}
.wrapper__content.expanded {
max-height: 1000px;
}
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div id="root"></div>
We can really check transition using height property and somehow control the distance like that
transition: max-height .5s ease-in-out;
Сomment below solves my problem
In reactjs I need to attach a linear progress bar as a bottom to div. I tried with a normal linear progress bar and attached the linear progress to the end of the div with the flex-end property.
Below is the code sandbox link for my implementation.
Code Sandbox Link:
codesandbox.io/s/linear-progress-bar-forked-udhxqz
But my requirement is the div should be as per the below screenshot
.
How can I achieve the below div with HTML and CSS changes?
I should implement using in reactjs
I was able to get your example working with a few CSS changes, below are the only two parts I needed to change:
.App {
overflow: hidden;
}
.emptyProgressBar {
border-radius: 0px;
}
.fillingProgressBar {
width: 102%;
}
Then in App.tsx, change your left style to -101, like the following:
left: props.percent - 101 + "%",
A working example forked from your sandbox is available here.
In header i have search field, which should have with same lice container.
Some how i need to make biger input, example:
[![enter image description here][1]][1]
My code jsFiddle
$(".search-input").on("mousedown", function () {
$(this).addClass('active');
$('.search_container').addClass('test')
});
$(".cancel-icon").on("mousedown", function () {
$('#search-content').hide();
$('.search-input').removeClass('active');
$('.search-input').val('');
$('.search_container').removeClass('test')
});
For some reason input don't wanna go biger -_-
create one more class of your name. I just call it as .some and it to div.search-field when input is active and remove it when cancel-icon is clicked.
.some{
flex-shrink: 0;
width: 100%;
transition: width 1s;
}
.search-field{
...
width: 50%;
...
}
$(".search-input").on("mousedown", function () {
...
$('.search-field').addClass('some');
});
$(".cancel-icon").on("mousedown", function () {
...
$('.search-field').removeClass('some');
});
display: flex making the .search-field shrink. In order to avoid that I added flex-shrink: 0
Updated
Added transition: width 1s to animate a width of .search-field and added an extra style width: 50% to an existing .search-field which doesn't change the existing size but it will make impact in transition.
I'm trying to fade a Modal in when it's clicked, and have the experience be smooth on mobile devices.
I'm setting both opacity to 0 and display to none. Setting opacity alone isn't enough, as it makes the area underneath unclickable.
#Modal {
display: none;
opacity: 0;
transition: opacity 500ms ease 0s;
}
Fade in Code:
$('#Modal').show();
$('#Modal').css('opacity','100');
However, the Modal doesn't fade in, it simply pops into existence.
Setting a setTimeout here works, but who wants a click delay for the fade in?
What's the best way to fade an element in with an opacity transition without chaining together massive properties like z-index, or some such nonsense?
Toogling display property it's bad way for fade element, Similar topics were already processed e.g: CSS3 transition doesn't work with display property
"display:none; removes a block from the page as if it were never there. A block cannot be partially displayed; it’s either there or it’s not. The same is true for visibility; you can’t expect a block to be half hidden which, by definition, would be visible! Fortunately, you can use opacity for fading effects instead."
quotation author:
Hashem Qolami
You should try to do this by deelay like here Animating from “display: block” to “display: none”
or try toogling class like here: http://jsfiddle.net/eJsZx/19/
CSS:
.Modal {
display: block;
opacity: 0;
transition: all 300ms ease 0s;
height: 0px;
overflow: hidden;
}
.ModalVisible {
display: block;
opacity: 1;
height: 50px;
}
Jquery:
$('button').on('click', function () {
$('#ModalId').addClass('ModalVisible');
});
Html:
<div id='ModalId' class="Modal" > content <br> content </div>
<button>show</button>
Why don't you use jQuery's $("selector").fadeIn() method?
The supposedly correct answer above implies that the OP is attempting a transition on display. They are not. Calling show() will set the display property to block. Then setting the opacity should theoretically trigger the transition from opacity:0.
A similar question has been answered here. To quote #WhoTheHellIsThat, the reason the transition is not triggered is...
...because of the way styles are figured out. Style changes are
expensive so they are effectively saved up until they are needed (a
recalc check like .offsetHeight is called or the next frame needs to
be drawn).
However the answer code in that question was Vanilla Javascript, and I couldn't make it work in jQuery. I found another answer that solved it in jQuery, using a class to trigger the transition.
Here is the full CSS...
#Modal {
display: none;
opacity: 0;
transition: opacity 500ms ease 0s;
}
#Modal.fade-in {
opacity: 1;
}
And here is the full JS:
$('#Modal').show(0, function() {
$(this).addClass('fade-in');
});
Here is a fiddle from RoryMcRossan's answer, demonstrating the solution.
I'm have a vertical stack of items to which the user can append one by clicking a button, roughly like this.
<ol>
<li><textarea></textarea></li>
<li><textarea></textarea></li>
</ol>
<a data-action="additem">Add another</a>
I'm trying to write a CSS animation so that when the new li is inserted, the "Add another" smoothly slides down to its new resting place. Fixed height on the li tags is not an option, and I'm trying to avoid using the max-height animation hack because it can have weird layout effects.
I figured out that I could animate margin-bottom from something to 0 and have the desired effect, but I can't figure out how in CSS to express that I want the current height of the element to which this rule is applied. Percentages are measured relative to the width of the element, which isn't what I need here, and I can't think of a clever trick using calc or the like to express what I want to the browser.
Suggestions?
EDIT
I'm using a template with a repeat binding to add the items to the list. The JS only pushes another object into an observable array, and the framework handles the actual DOM insertion. The li tag has on it the following CSS to get it to enter smoothly:
animation: append forwards .5s;
And append is defined as:
#keyframes append {
from {
transform: translateX(10%);
opacity: 0;
margin-bottom: _____;
}
to {
transform: none;
opacity: 1;
margin-bottom: 0;
}
}
Not currently...
I've come up against this frustrating issue a number of times, always trying to either animate a non-numeric value, access a specific property of the current element as an animation value, or animate an unspecified value to a specified one. Generally I always have to fall back to either some form of not-quite-perfect max-height animation (like you've already mentioned) or use a mixture of CSS and JavaScript/jQuery.
For your issue there are a few options, but none are exactly what you're after.
css only version (using duplicated markup and another animation)
http://jsfiddle.net/7m8F9/2/
http://jsfiddle.net/7m8F9/3/ <-- improved version using bottom and position:relative
http://jsfiddle.net/7m8F9/5/ <-- even better version, going back to translateY
One trick often used with CSS-only hacks, is to duplicate markup — in this instance, the link iteself — and place it within parent wrappers that will be turned on or off by different means. The downsides to this method are that you get a rather ugly markup, and in this particular instance a bullet-number that appears jarringly (because of having to move the opacity animation from the li to the textarea).
The benefits of this method however are that by moving the link inside the li you can use -100% on the y-axis with a translate, or another offset method. Oddly though I can't work out what translateY(-100%) is calculating based upon... it doesn't seem to be the parent height, perhaps it is the height of itself. For this reason I've updated the fiddle to use bottom and relative positioning instead, although in Firefox (on mac) this glitches briefly.
It does seem to be that translateY is calculating percentage based on it's own height, so in order to get around this problem I've had to make use of position absolute and force the the link layer to assume the same dimensions as the li... annoying, as it involves z-indexing the textarea above the link, and an internal span to offset the link text, but at least it does work.
The following code works in the latest Firefox, and would work in other modern browsers if all the different browser-prefixes were correctly used to define the animation keyframes, I don't have time to set them all up right now however.
markup:
<ol class="list">
<li><textarea></textarea><a class="add" href="#"><span>Add another</span></a></li>
<li><textarea></textarea><a class="add" href="#"><span>Add another</span></a></li>
</ol>
css:
ol li {
position: relative;
}
ol li .add {
display: none;
}
ol li:last-child .add {
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
width: 100%;
height: 100%;
display: block;
animation-duration: 1s;
animation-name: slide;
}
ol li:last-child .add span {
position: absolute;
bottom: -20px;
}
.list li textarea {
position: relative;
animation-duration: 1s;
animation-name: append;
z-index: 1;
}
#keyframes append {
from {
transform: translateX(10%);
opacity: 0;
}
to {
transform: none;
opacity: 1;
}
}
#keyframes slide {
from {
transform: translateY(-100%);
}
to {
transform: none;
}
}
javascript version (code triggered translations)
http://jsfiddle.net/7m8F9/1/
The following obviously doesn't take into account the fact that you are using a template engine to power your DOM manipulations, but all the code needs to work properly is a before and after height of the list (to calculate the difference in height), and an event to trigger at the point where the new list item is added.
Sadly it is not yet possible to do this all in pure CSS, at least not as far as I have seen, perhaps once calc has leveled up...? Or perhaps if some way is introduced to reference the current elements dimensions, not just it's offset parent.
It should be noted I didn't have Internet Explorer around to test this with, but all other modern browsers seem happy.
markup:
<ol class="list">
<li><textarea></textarea></li>
<li><textarea></textarea></li>
</ol>
<div class="add">
Add another
</div>
javascript (with jQuery):
function prefix(){
for ( var a = ['Webkit','Moz','O','ms'], i=0, l = a.length; i<l; i++ ) {
if ( document.body.style[a[i]+'AnimationName'] !== undefined ) {
return { js: a[i], css: '-' + a[i].toLowerCase() + '-' };
}
}
return { css:'', js:'' };
}
$(function(){
$('.add a').click(function(e){
e.preventDefault();
var pref = prefix(),
link = $(this).parent(),
list = $('.list'),
lihi = list.height(),
liad = $('<li><textarea></textarea></li>').appendTo(list),
lihd = lihi - list.height();
link.css(pref.css + 'transform', 'translateY(' + lihd + 'px)');
setTimeout(function(){link.addClass('translate-zero transition-all');},0);
setTimeout(function(){
link.css(pref.css + 'transform', '');
link.removeClass('translate-zero transition-all');
},500);
});
});
css:
.transition-all {
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
-ms-transition: all 0.5s;
-o-transition: all 0.5s;
transition: all 0.5s;
}
.translate-zero {
-webkit-transform: translateY(0) !important;
-moz-transform: translateY(0) !important;
-ms-transform: translateY(0) !important;
-o-transform: translateY(0) !important;
transform: translateY(0) !important;
}
.list li {
animation-duration: 1s;
animation-name: append;
}
#keyframes append {
from {
transform: translateX(10%);
opacity: 0;
}
to {
transform: none;
opacity: 1;
}
}
redesign version
A number of times I have hit a similar issue, only to find a redesign helps do away with the problem and can often actually improve usability. In your case it may be best to place the "add link" above the list (or top right), or integrate the button as a floating icon somewhere... where-ever you put it, it is best to try and keep it in a static location, moving interaction points can be annoying for users, especially if they wish to add more than one item in quick succession.
The simplest solution that i could think of is this.
When you add a new li element, just append it in the dom.
liMarkup = '<li><textarea></textarea></li>'
$('ol').append(liMarkup);
$('ol').find('li').last().css('display','none');
$('ol').find('li').last().show('fast');
This would work as per your requirement :) I hope it helps.
Working Jsfiddle
EDIT: Its easy and better to do it in JS.