The Issue
Sometimes, we want our container to dynamically fit the size of its content, such as navigation bar with dropdown menu.
The size of the content may not always be a fixed value, and CSS transition hates that.
We know CSS style like this will create a smooth transition.
.menu{
height:0;
transition: 0.3s;
}
.menu:hover{
height:300px;
}
However, this will not work since css transition needs a numeric value to work with.
.menu{
height:0;
transition: 0.3s;
}
.menu:hover{
height:fit-content;
}
Method 1
We can use ref
and getBoundingClientRect
to get the content's dimension
Here is a demo:
and the code of the container:
function DynamicContainer({ children, className, style }) {
const content = useRef(null);
const [rect, setRect] = useState({ width: 0, height: 0 });
useEffect(() => {
setRect(content.current.getBoundingClientRect());
}, [children]); //Only update dimension when children change
return (
<div
className={className}
style={{
transition: "0.3s",
height: `${rect.height}px`,
width: `${rect.width}px`,
overflow: "hidden",
...style
}}
>
{/* The inter container for calculating the content dimension*/}
<div
ref={content}
style={{
width: "fit-content",
height: "fit-content"
}}
>
{children}
</div>
</div>
);
}
Noted: This container will only work well when the dimension of each child is static.
We will talk how to handle child components with dynamic dimension next time.
Thanks All.
Top comments (0)