CSS Animate button to appear - css

In the React app I'm building, I would like a button to be hidden until certain conditions are met. Then I'd to animate it in from underneath another element.
At the moment I am always rendering the button and adding a class of "hidden" when I'd like it hidden.
The SASS looking something like this:
button {
display: inline-block;
width: 100%;
height: 63px;
transition: height 250ms ease-in-out;
font-size: 24px;
&.hidden {
height: 0;
}
}
But when the button hides, the element gets smaller, but the text is still visible. Similar to this: https://jsfiddle.net/dtu56e1j/
What am I doing wrong?
Or is there a better way to get a button to animate in?

IMO the other answers provide working, but complicated solutions to your problem. Simply put, you're missing a single CSS property - overflow: hidden.
I created this StackBlitz to illustrate the point.
However, the only modification necessary to the original code is this:
button {
overflow: hidden;
[...]
}
Fiddle to better match use-case: https://jsfiddle.net/smn6xgv2/
Because the button element has some internal padding, setting height: 0 doesn't completely remove the element from the display. To address that issue, we wrap the button inside a div and then animate the height of the div.
Additionally, the div should be left with the default display: block. In the original example, the display: inline-block causes the browser to reserve a minimum height of line-height. More info in this SO question

With a little work you could use translateY to get this done nicely
const el = document.querySelector("#testButton");
setInterval(() => {
el.classList.toggle("hidden");
}, 2000);
button {
display: inline-block;
background-color: darkblue;
color: white;
width: 100%;
height: 63px;
transition: transform 250ms ease-in-out;
font-size: 24px;
}
button.hidden {
transform: translateY(63px); /* or -63px to invert */
}
/* Make a wrapper class so that your button disappears on transform */
.wrapper {
height: 63px;
overflow: hidden;
}
<div class="wrapper">
<button id="testButton">My Button!</button>
</div>

Related

Does CSS animation cause Angular 2 to stop rendering?

I can see from console.logs that the variable is updating every second. But the {{variable}} in the HTML isn't. If I select the text it updates, or if the container div is animated the variable updates.
In the .ts I have a
ngOnInit() {
this.ref.detectChanges();
}
and I tried calling this.ref.detectChanges() every second when I update the variable.
All of the {{}} are not being updated until something else happens. A *ngIf displays something, or a CSS animation is triggered. No errors in the console.
CSS animation for the drawer :
.moveOutProductDrawer{
left: -250px;
animation: scootch 0.3s forwards;
}
#keyframes scootch {
100% { left: -250px !important; }
}
And in another part of the .ts I'm changing the height and width directly.
Has anyone experienced this before? Does the presence of CSS animation mess with Angular?
For some reason, when I change how the window is positioned into the center of the screen, everything is back to normal.
.bigFlexcontainer{
/* display: flex;
align-items: center;
justify-content: center; */
position: relative;
width: 100%;
height: 100%;
}
with position relative and no more flex, the variables are updating correctly and all is well. Probably shouldn't matter, but in this case it solved the problem.

Can I apply a CSS transition to the overflow property?

I'm trying to set a transition-delay to the overflow property of body when a div is clicked by adding a class to the body as follows:
$("div").click(function(){
$("body").addClass("no_overflow");
});
div{
background:lime;
height:2000px;
}
.no_overflow{
overflow:hidden;
}
body{
overflow:auto;
transition: overflow 0 2s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>I'm div</div>
However, this doesn't seem to work (there's no delay). Am I doing anything wrong here?
I know this can be achieved by using setTimeout function, but was wondering why can't this be achieved using css transitions? Are there any specific style properties to which css transitions can be applied?
There are many properties that can't be transitioned. overflow is among them; the render engine has no idea how to transition between "hidden" and "shown", because those are binary options, not intervals. This is the same reason why you can't transition between display: none; and display: block; (for example): there are no in-between phases to use as transitions.
You can see a list of properties you can animate here on Mozilla Developer Network.
You can simulate a delay with animation:
$("div").click(function() {
$("body").addClass("no_overflow");
});
div {
background: lime;
height: 2000px;
}
.no_overflow {
overflow: hidden;
/* persist overflow value from animation */
animation: 7s delay-overflow;
}
body {
overflow: auto;
}
#keyframes delay-overflow {
from { overflow: auto; }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>I'm div</div>
You'll have to apply a separate animation to .body if you want a delay on removeClass, and also to take care that the two animations don't overlap or they'll cancel each other out.
overflow isn't CSS animatable property. You can see full list of animatable CSS properties there.
In case someone is looking at the answer, like I was, for a way to animate the cropping of an element which requires overflowing - here is the solution that worked for me: the clip-path css property which is animatable and very versatile.
Here is a cool tool to play around with, in order to get the proper start / end values for an animation: https://bennettfeely.com/clippy/.
Dmitry's answer should be the only accepted answer, as it is a pure CSS solution applying delay to "non-animatable" properties. However it's worth to mention, that the CSS rule applying animation should be "triggerable" each time when it is needed.
For instance, the following code does not work:
#keyframes show-overflow {
from { overflow: hidden; }
}
.hideable, .overlay {
font-size: 36px;
height: 50px;
}
.hideable {
transition: height 2s;
overflow: visible;
animation: show-overflow 2s; /* this line should be in separate "triggerable" CSS rule to work */
}
.hideable.hidden {
height: 0;
overflow: hidden;
}
<button onclick="document.getElementById('hideable').classList.toggle('hidden')">
Clik HERE to hide/show the text below
</button>
<div id='hideable' class='hideable'>
This is the text to hide and show.
</div>
<div class='overlay'>
This is overlaying text
</div>
But after moving the marked property to a separate CSS rule, everything works as expected:
#keyframes show-overflow {
from { overflow: hidden; }
}
.hideable, .overlay {
font-size: 36px;
height: 50px;
}
.hideable {
transition: height 2s;
overflow: visible;
}
.hideable:not(.hidden) {
animation: show-overflow 2s; /* now this works! */
}
.hideable.hidden {
height: 0;
overflow: hidden;
}
<button onclick="document.getElementById('hideable').classList.toggle('hidden')">
Clik HERE to hide/show the text below
</button>
<div id='hideable' class='hideable'>
This is the text to hide and show.
</div>
<div class='overlay'>
This is overlaying text
</div>
It makes sense that you can't transition between binary attributes for example overflow: hidden; and overflow: visible but it would have been really nice if instead of "transitioning" then it would be like (in js pseudo code:
setTimeout("applyOverflowVisible()", transitionTime);
But of course you can do this yourself in JavaScript but then you are splitting the code between places and it can make it difficult to understand by someone else. I guess using things like React helps but even there I would want to avoid mixing css into the js.

div:focus being used to transition height, clicking on iframe elements reverts transition

I'm trying to have my website have drop-down divs when clicked, allowing you to examine the inline widgets inside the divs. However, iframe and other elements that aren't strictly images cause the div to transition back to its original state, causing the menu to collapse as though the user had clicked out of the div area.
Here's what I got:
.music-block {
width: 350px;
height: 90px;
background-color: #bc37ff;
overflow: hidden;
-webkit-transition: 0.6s;
transition: 0.6s;
}
.music-block:focus {
max-height: 952px;
}
.music-block:hover {
cursor: pointer;
}
<div class="music-block" tabindex="1">
<p>
<h1>MUSIC</h1>
</p>
Text.
</div>
<p>
<iframe style="border: 0; width: 350px; height: 654px;" src="https://bandcamp.com/EmbeddedPlayer/album=3599654224/size=large/bgcol=ffffff/linkcol=7137dc/transparent=true/" seamless>toothbops - EP by toothbops
</iframe>
</p>
</div>
Here's an example of what I mean with the menu collapsing when you click on iframes (in this case, a bandcamp widget): http://jsfiddle.net/6m52jxtj/
Ok, I can see two posible solutions to your problem, a js way and a css way(there are probably more than that but this comes to mind at the moment :) )
For the css way, you'll need to add a input[tpye='checkbox'] and a label on top of the markup, make the label with height and width of the initial music-block and you're good to go: check out the js fiddle
#trigger-music-block{
display: none;
}
#trigger-music-block + label{
position: absolute;
top: 0; left: 0;
height: 90px; width: 350px;
cursor: pointer;
}
#trigger-music-block:checked + label + .music-block{
height: 952px;
}
For the js way, you can just add a extra class on .music-block when a user clicks it, like this:
check out js fiddle
$('.music-block').click(function(){
$(this).addClass('expanded');
});

How to hide/show the content of a div with dynamic height?

I am trying to develop a small module (like the collapse component of twitter bootstrap).
I don't know how to treat the content of the div which is growing up/down, it could take me many descriptions, nothing's better than an example: Collapse deployment.
You can see a div.container which is the block destined to grow up/down.
Here i declare height: 50px to illustrate a state of the deployment.
Is there a way to hide the content (here a part of the text) that is out of the height of a parent div ?
I like the idea that we can access a content only by deploying another one, but i don't really don't understand how to make it happen properly in CSS.
Like this? JSFiddle example: http://jsfiddle.net/SW86B/1/
Updated CSS
.header {
background-color: green;
height:20%;
}
.container {
background-color: red;
height: 0;
overflow: hidden;
-webkit-transition: height 0.2s ease;
-moz-transition: height 0.2s ease;
transition: height 0.2s ease;
}
.container.open { height: 50px;}
p { margin: 0; }
Use jQuery to toggle states
$('button').on('click', function(event){
$('.container').toggleClass('open');
});
I am not sure that i understand what you are trying but you can use
overflow:hidden;
Demo here - http://jsfiddle.net/JjPcy/1/
Set the div.container's overflow css properoty to hidden.
div.container { overflow: hidden; }
Also make a class for instance called auto-width that has auto width:
div.auto-width { width: auto !important; }
Then use jQuery to toggle the class and reveal the data inside the container:
$('div.header button').click(function() {
$('div.container').toggleClass('auto-width');
});
Here's the demo: http://jsfiddle.net/VE9WR/3/
It could be done in so many ways. it depends on what you're looking for ;)

animate inline element scroll full width

for the following paragraph, I want to animate to scroll span element upon mouse hover. It will scroll to the right until the end.
<div class="one_line">
<span>
NoMagic framework doesn't try to put anything into the blackbox. We hope you read the core source code and try to get fully understanding before you start to using it. And we hope you forking our project and creating your own database helper function sets based on your need.
Using NoMagic, you will turn the MySQL database into a schemaless solution, the schemaless database will save your time so that you don't need to spend to much time in planning database table structure.
</span>
</div>
the css I already have
.one_line {
line-height: 1.5em;
height: 1.5em;
position: relative;
width: 600px;
overflow-x: hidden;
span {
white-space: nowrap;
height: 100%;
display: inline-block;
position: absolute;
&:hover {
animation-name: scroll;
animation-duration: 6s;
}
}
}
#keyframes scroll {
50% {
left: 100%;
}
}
Up to my knowledge using CSS animate we can only animate the entire tag itself but not the content in it (i.e.) in this case we can move the entire span across the page dimension but not the text inside it. So i made it using transform property which is more flexible.
I have a jsfiddle here to demonstrate this.
CSS Animate code that i had changed:
#keyframes scroll {
0% {
transform:translateX(0);
}
100% {
transform:translateX(-100%);
}
}
Hope this will be useful.

Resources