css key-frames animating dynamic height
Instead of animating height
, try animating transform: translateY()
as follows (you will get a true sliding effect):
@keyframes slideDown{
from {
transform: translateY(-100%);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
CSS height animation on element with dynamic height
Remove the height: 200px;
, so you have both animate for expand and collapse.
Also, use the following to add animate on new line:
@keyframes lineInserted {
from {
height: 0;
}
to {
height: 20px; /* your line height here */
}
}
div[contenteditable] > div {
animation-duration: 0.3s;
animation-name: lineInserted;
transition: height 0.3s;
}
document.querySelector('#button').addEventListener('click', function() {
document.querySelector('.text').classList.toggle('max');
});
.text {
background: green;
color: #fff;
transition: all .3s ease-in-out;
min-height: 20px;
max-height: 90vh;
overflow: auto;
}
.max {
transition: all .3s ease-in-out;
min-height:90vh;
}
@keyframes lineInserted {
from {
height: 0;
}
to {
height: 20px; /* your line height here */
}
}
div[contenteditable] > div {
animation-duration: 0.3s;
animation-name: lineInserted;
transition: height 0.3s;
}
<div class="text" contentEditable="true"></div>
<button id="button">Click</button>
CSS keyframe -- start from dynamic height
Give the list items a max-height
and then use transition
to get to a min-height
when clicked. Use overflow: hidden
on the list items to contain items that would push the list item past 100px.
Working Example
In this example, all list items expand on click. Obviously, you would change the javascript to just expand the list item that was clicked.
var expand = document.getElementById("items");
expand.addEventListener('click', function() { this.classList.toggle('click');}, false);
* { margin: 0; padding: 0; list-style: none;}ul { background: #FF0; padding: 1px 0;}li { background: #F00; margin: 10px; transition: all 1s; max-height: 100px; overflow: hidden;}.click li { min-height: 200px;}
<ul id="items"> <li>Item</li> <li>Larger <br />Item</li> <li>Largest <br />Item <br />In <br />this <br />List</li></ul>
How to animate dynamic width content?
You can do this with a keyframe animation. The key is setting a max-width
greater than how big the element will be. Note that the animation timing takes into account the total max-width.
CSS
.test {
animation-name: test;
animation-duration: 1s;
animation-direction: forwards;
overflow: hidden;
white-space: nowrap;
}
@keyframes test {
0% {
max-width: 0;
}
100% {
max-width: 200px;
}
}
and then you need to add the class to your dynamic object
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<div className="container">
<button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? "Hide" : "Show"}
</button>
{isOpen && <div class='test'>Dynamic Content</div>}
<input type="text" />
</div>
);
}
You can toggle the animation duration and make it happen on removal too if you want but I'll leave it to you to play with.
https://codesandbox.io/s/6wj6z1ppxr
CSS keyframe animation for n number of elements
It can only be done in CSS if you hardcode the values (e.g: you know how many items there are). To do it for any number of items, you need js.
Here's a vanilla js class for it:
class BannerAnimation {
#index
el
items
duration = 4000
animationDuration = 420
constructor(props) {
const { start, ...args } = props
Object.assign(this, args)
this.#index = start || 1
if (!this.items || !this.items.length) {
this.items = [...this.el.children].map((c) => c.innerHTML)
}
;[...this.el.children].forEach((c) => c.remove())
this.appendChild(this.#index - 1)
this.el.style.setProperty('--dur', `${this.animationDuration}ms`)
Object.assign(this.el.style, {
display: 'block',
height: this.el.children[0].offsetHeight + 'px'
})
setTimeout(this.start, this.duration)
}
start = () => {
const div = this.appendChild(this.#index)
const first = this.el.children[0]
first.style.marginTop = `-${first.offsetHeight}px`
this.el.style.height = div.offsetHeight + 'px'
this.el.classList.add('animating')
setTimeout(this.end, this.animationDuration)
}
end = () => {
this.el.classList.remove('animating')
this.el.children[0].remove()
this.#index = (this.items.length + this.#index + 1) % this.items.length
setTimeout(this.start, this.duration)
}
appendChild = (i) => {
const div = document.createElement('div')
div.innerHTML = this.items[i]
this.el.appendChild(div)
return div
}
}
new BannerAnimation({
el: banner,
duration: 1000,
// items: [1, 2, 3]
})
#banner {
overflow: hidden;
transition: height 0ms cubic-bezier(.4, 0, .2, 1);
transition-duration: var(--dur);
}
#banner div:first-child {
margin-top: 0px
}
#banner div {
transition: margin-top 0ms cubic-bezier(.4, 0, .2, 1);
transition-duration: var(--dur);
}
<div id="banner">
<div>One</div>
<div>
Two
<div style="height: 100px; border: 1px solid red;"></div>
</div>
<div>Three</div>
<div>Four</div>
<div>Five<br>and a half...</div>
<div>Six</div>
<div>Seven</div>
</div>
<hr>
how to animate width and height 100% using css3 animations?
You need to specifiy 100% of something..in this case, the html/body
* { margin: 0; padding: 0;}html,body { height: 100%;}div { background: tomato; width: 100px; height: 100px; -webkit-animation: animateThis 1s ease-in; -webkit-animation-fill-mode: forwards;}@-webkit-keyframes animateThis { 0% { width: 100px; height: 100px; } 100% { width: 100%; height: 100%; }}
<div></div>
Related Topics
Twitter Bootstrap Accordion and Button Dropdown Overflow Issue
Definition List with Inline Pairs
What Is The Meaning of an Ampersand in Less Selectors
Using CSS Mix-Blend-Mode with a Child of a Position Fixed Element
Font Family Open Sans Not Being Used
Bootstrap Collapse Accordion - Default Expand/Collapse
Bootstrap 4 Center Pagination in Column
CSS Transform Square into Thinner Rhombus
How to Make Webgl Canvas Transparent
Web Fonts and Providing Fallback Fonts
How to Set Different Font-Weight for Fallback Font
How to Audit Multiple Pages with Chrome Developer Tools
Make a <Textarea> Fill Remaining Height
How Necessary Are CSS3 Vendor Prefixes Right Now
How Do Browsers Parse/Render CSS
How to Make an Svg Masked Image Compatible with Internet Explorer