How to Animate Width to Auto Using jQuery
Animating an element’s width from 0 to
'auto' cannot be achieved natively with jQuery’s
.animate() method because it requires numeric values to
calculate frame-by-frame interpolation. The safest and most robust
solution is to temporarily calculate the element's rendered pixel width
at 'auto', instantly restore it to 0, animate
to the measured pixel value, and finally set the CSS width back to
'auto' upon completion to preserve responsive behavior.
The Core Problem
Passing { width: 'auto' } directly into jQuery's
.animate() fails silently or causes an abrupt jump:
// This does NOT work
$('#target').animate({ width: 'auto' }, 400);Because 'auto' is a keyword rather than a fixed scalar
value, jQuery cannot compute intermediate states.
The Solution: Measure, Animate, and Reset
Browsers do not repaint the screen between synchronous JavaScript
execution lines. This allows you to set the element to
width: 'auto', measure its computed width, revert it back
to 0, and start the animation without any visual
glitching.
Here is the standard implementation:
function animateWidthToAuto(selector, duration) {
var $el = $(selector);
// 1. Temporarily apply 'auto' and read the computed width
var targetWidth = $el.css('width', 'auto').width();
// 2. Revert instantly back to 0
$el.css('width', 0);
// 3. Animate to the measured numerical value
$el.stop().animate({ width: targetWidth }, duration, function () {
// 4. Reset to 'auto' so content remains responsive
$(this).css('width', 'auto');
});
}Handling Invisible or Hidden Elements
If the element starts with display: none,
.width() returns 0. To accurately measure its
width, temporarily force layout visibility without causing a visual
flash:
function animateHiddenWidthToAuto(selector, duration) {
var $el = $(selector);
// Measure while element is invisibly rendered
$el.css({
position: 'absolute',
visibility: 'hidden',
display: 'block',
width: 'auto'
});
var targetWidth = $el.width();
// Restore original positioning and initialize starting width
$el.css({
position: '',
visibility: '',
display: 'block',
width: 0
});
// Run the animation
$el.stop().animate({ width: targetWidth }, duration, function () {
$(this).css('width', 'auto');
});
}Essential Considerations
overflow: hidden: Always applyoverflow: hiddenvia CSS to the animating container to prevent its internal text or children from wrapping unexpectedly or spilling outside during the transition.box-sizing: Ensure the element usesbox-sizing: border-boxto avoid width recalculation errors if padding or borders are present.- Responsive Cleanup: Step 4 (setting
width: 'auto'in the complete callback) is critical. Leaving a fixed pixel width will prevent the element from adapting to future layout changes, font size updates, or window resizes.