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)