Resizing motion

Animate width and height changes, to be used with caution.

This page demonstrates how to animate width, height or both which is notoriously unperformant, (opens new window). Test your app over low powered devices, you may want to avoid this if you can see it impacting FPS.

useResizing

Width

Animates the container width as items are added or removed horizontally.

import { useCallback, useState } from 'react'; import { cssMap, cx, jsx } from '@atlaskit/css'; import { Label } from '@atlaskit/form/label/default'; import { AtlassianIcon } from '@atlaskit/logo/atlassian-icon'; import { useResizing } from '@atlaskit/motion/use-resizing'; import { Box, Inline } from '@atlaskit/primitives/compiled'; import Toggle from '@atlaskit/toggle'; import { token } from '@atlaskit/tokens'; const styles = cssMap({ container: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', borderRadius: token('radius.xxlarge'), borderWidth: token('border.width'), borderStyle: 'solid', borderColor: token('color.border'), backgroundColor: token('elevation.surface'), marginBlockStart: token('space.200'), }, logo: { display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', fontWeight: token('font.weight.medium'), paddingBlockEnd: token('space.100'), paddingBlockStart: token('space.100'), paddingInlineEnd: token('space.200'), paddingInlineStart: token('space.200'), }, small: { width: '50px', }, large: { width: '100px', }, }); const MotionResizingWidth = (): JSX.Element => { const [expand, setExpand] = useState(false); const toggleExpand = useCallback(() => { setExpand((expand) => !expand); }, []); const resizingProps = useResizing({ dimension: 'width', duration: token('motion.duration.xxlong'), easing: token('motion.easing.out.practical'), }); return ( <Box> <Inline alignBlock="center"> <Label htmlFor="inline-toggle-expand">Toggle expand</Label> <Toggle id="inline-toggle-expand" onChange={toggleExpand} /> </Inline> <Box {...resizingProps} xcss={styles.container}> <Box xcss={cx(expand ? styles.large : styles.small, styles.logo)}> <AtlassianIcon size="medium" /> </Box> </Box> </Box> ); }; export default MotionResizingWidth;

Height

Animates the container height as items are added or removed vertically.

import { useCallback, useState } from 'react'; import { cssMap, cx, jsx } from '@atlaskit/css'; import { Label } from '@atlaskit/form/label/default'; import { AtlassianIcon } from '@atlaskit/logo/atlassian-icon'; import { useResizing } from '@atlaskit/motion/use-resizing'; import { Box, Inline } from '@atlaskit/primitives/compiled'; import Toggle from '@atlaskit/toggle'; import { token } from '@atlaskit/tokens'; const styles = cssMap({ container: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', borderRadius: token('radius.xxlarge'), borderWidth: token('border.width'), borderStyle: 'solid', borderColor: token('color.border'), backgroundColor: token('elevation.surface'), marginBlockStart: token('space.200'), }, logo: { display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', fontWeight: token('font.weight.medium'), paddingBlockEnd: token('space.100'), paddingBlockStart: token('space.100'), paddingInlineEnd: token('space.200'), paddingInlineStart: token('space.200'), }, small: { height: '50px', }, large: { height: '100px', }, }); const MotionResizingHeightNew = (): JSX.Element => { const [expand, setExpand] = useState(false); const toggleExpand = useCallback(() => { setExpand((expand) => !expand); }, []); const resizingProps = useResizing({ dimension: 'height', duration: token('motion.duration.xxlong'), easing: token('motion.easing.out.practical'), }); return ( <Box> <Inline alignBlock="center"> <Label htmlFor="inline-toggle-expand">Toggle expand</Label> <Toggle id="inline-toggle-expand" onChange={toggleExpand} /> </Inline> <Box {...resizingProps} xcss={styles.container}> <Box xcss={cx(expand ? styles.large : styles.small, styles.logo)}> <AtlassianIcon size="medium" /> </Box> </Box> </Box> ); }; export default MotionResizingHeightNew;

Width and Height

Animates both width and height simultaneously as the grid grows or shrinks.

import { useCallback, useState } from 'react'; import { cssMap, cx, jsx } from '@atlaskit/css'; import { Label } from '@atlaskit/form/label/default'; import { AtlassianIcon } from '@atlaskit/logo/atlassian-icon'; import { useResizing } from '@atlaskit/motion/use-resizing'; import { Box, Inline } from '@atlaskit/primitives/compiled'; import Toggle from '@atlaskit/toggle'; import { token } from '@atlaskit/tokens'; const styles = cssMap({ container: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', borderRadius: token('radius.xxlarge'), borderWidth: token('border.width'), borderStyle: 'solid', borderColor: token('color.border'), backgroundColor: token('elevation.surface'), marginBlockStart: token('space.200'), }, logo: { display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', fontWeight: token('font.weight.medium'), paddingBlockEnd: token('space.100'), paddingBlockStart: token('space.100'), paddingInlineEnd: token('space.200'), paddingInlineStart: token('space.200'), }, small: { width: '50px', height: '50px', }, large: { width: '100px', height: '100px', }, }); const MotionResizingBoth = (): JSX.Element => { const [expand, setExpand] = useState(false); const toggleExpand = useCallback(() => { setExpand((expand) => !expand); }, []); const resizingProps = useResizing({ dimension: 'both', duration: token('motion.duration.xxlong'), easing: token('motion.easing.out.practical'), }); return ( <Box> <Inline alignBlock="center"> <Label htmlFor="inline-toggle-expand">Toggle expand</Label> <Toggle id="inline-toggle-expand" onChange={toggleExpand} /> </Inline> <Box {...resizingProps} xcss={styles.container}> <Box xcss={cx(expand ? styles.large : styles.small, styles.logo)}> <AtlassianIcon size="medium" /> </Box> </Box> </Box> ); }; export default MotionResizingBoth;

useResizingHeight

Caution

We are planning on deprecating useResizingHeight. Please use the useResizing hook instead.

Bitbucket

import { useState } from 'react'; import { css, jsx } from '@compiled/react'; import Button from '@atlaskit/button/default/button'; import { Label } from '@atlaskit/form/label/default'; import { JiraSoftwareIcon } from '@atlaskit/logo/jira-software-icon'; import { BitbucketIcon, ConfluenceIcon, OpsgenieIcon, StatuspageIcon } from '@atlaskit/logo'; import FadeIn from '@atlaskit/motion/fade-in'; import StaggeredEntrance from '@atlaskit/motion/staggered-entrance'; import { useResizingHeight } from '@atlaskit/motion/use-resizing-height'; import { token } from '@atlaskit/tokens'; import { Centered } from '../utils/containers'; const logos = [ [<BitbucketIcon size="small" />, 'Bitbucket'], [<ConfluenceIcon size="small" />, 'Confluence'], [<JiraSoftwareIcon size="small" />, 'Jira Software'], [<OpsgenieIcon size="small" />, 'Opsgenie'], [<StatuspageIcon size="small" />, 'Statuspage'], ]; const searchTerm: { [key: string]: string } = { s1: 'dev', s2: 'design', s3: 'software', s4: 'ops', s5: 'all', }; const containerStyles = css({ textAlign: 'center', '> *': { marginInlineEnd: token('space.025'), }, }); const centeredContainerStyles = css({ width: '100%', maxWidth: '500px', borderRadius: token('radius.small', '3px'), boxShadow: token('elevation.shadow.overlay'), marginBlockEnd: token('space.800'), paddingBlockEnd: token('space.100'), }); const logoContainerStyles = css({ display: 'flex', fontSize: '16px', fontWeight: token('font.weight.medium'), paddingBlockEnd: token('space.200'), paddingBlockStart: token('space.200'), paddingInlineEnd: token('space.200'), paddingInlineStart: token('space.200'), '&:hover': { backgroundColor: token('color.background.accent.gray.subtler'), }, }); const headerStyles = css({ fontWeight: 300, marginBlockEnd: token('space.0'), marginBlockStart: token('space.0'), marginInlineEnd: token('space.0'), marginInlineStart: token('space.100'), }); const inputContainerStyles = css({ marginBlockStart: token('space.300'), textAlign: 'start', }); const MotionResizeHeightExample = (): JSX.Element => { const [num, setNum] = useState(1); return ( <div> <div css={containerStyles}> {[1, 2, 3, 4, 5].map((number) => ( <Button testId={`button--${number}`} key={number} isSelected={num === number} onClick={() => { setNum(number); }} > {number} </Button> ))} </div> <Centered> <div data-testid="menu" {...useResizingHeight()} css={containerStyles}> <div css={inputContainerStyles}> <Label htmlFor="input-options">Motion options</Label> <input id="input-options" type="text" readOnly value={searchTerm[`s${num}`]} css={centeredContainerStyles} /> </div> <StaggeredEntrance columns={1}> {Array(num) .fill(undefined) .map((_, index) => ( <FadeIn key={index}> {(motion) => ( <div ref={motion.ref} className={motion.className} style={motion.style} css={logoContainerStyles} > {logos[index][0]} <h3 css={headerStyles}>{logos[index][1]}</h3> </div> )} </FadeIn> ))} </StaggeredEntrance> </div> </Centered> </div> ); }; export default MotionResizeHeightExample;
Was this page helpful?
We use this feedback to improve our documentation.
© 2026 AtlassianTrademark, (opens new window)Privacy, (opens new window)License