Auto Sizing
How to have your components size automatically on the Framer canvas.
With Auto Size, Framer now has the ability to accurately measure any content on the canvas and add UI to it accordingly. When building code components this means you can write styles as you are used to on the web and Framer will figure out the rest.
What does this mean in practice? A list that changes the number of items in its list will change accordingly on the Framer canvas.
#Sizing Options
There are four settings for code component layout in Framer: auto
, fixed
, any
, and any-prefer-fixed
. These can be set for width or height axis individually, using @framerSupportedLayoutWidth
and @framerSupportedLayoutHeight
annotations.
auto
— The component will dictate its own size.fixed
— The component is in a fixed size container and can fill 100% of its width & height.any
— The user can switch betweenauto
andfixed
sizing by using the controls in the properties panel. It will insert with its sizing set toauto
by default.any-prefer-fixed
— The same as theany
option however it will insert with its sizing set tofixed
by default.
#Specifying Options
The default layout setting for all components in Framer is any
. To select different layout options for your component you'll need to add an annotation.
This annotation is a special comment that Framer reads and uses to accordingly set options for your component. Make sure this comment is on the lines directly above where you declare your component.
The following code will make your component have auto-sizing for width, but not height. You can make these two properties any combination of sizing options as long as you have both width & height specified at all times.
/*** @framerSupportedLayoutWidth auto* @framerSupportedLayoutHeight fixed*/export function Toggle(props) {
Intrinsic Size
These annotations let Framer know what size your component should be inserted into the canvas when fixed sizing is enabled. In this case, it will insert with a width of 200px and a height of 200px.
/*** @framerIntrinsicWidth 300* @framerIntrinsicHeight 250** @framerSupportedLayoutWidth fixed* @framerSupportedLayoutHeight fixed*/export function Toggle(props) {
#
#Using Auto-Sizing
By default, all Code Component have any
sizing enabled, which means components will size automatically when inserted onto the canvas, and display a control that allows users to switch between auto
and fixed
sizing.
#Supporting the default any
By spreading the style prop into your parent container style properties with {...style}
, Framer will override the width and height when auto-sizing is turned off (fixed
sizing) by passing down { width: "100%", height: "100%" }
via the style prop. While doing this, Framer wraps your component in a fixed-sized container set to the user-defined size on the canvas.
Here is an example of a component that will define its own size 50px height and 50px width when auto-sizing is enabled, then grow to fit your custom container size when fixed sizing is turned on.
export function Toggle(props) { const { style } = props
return ( <motion.div style={{ width: 50, height: 50, ...style }} /> )}
#Auto-Sizing Dynamically
If you want to auto-size your component based on logic or state changes, using a useLayoutEffect
will work best with our measuring system.
Generally you'll want to use this approach when controlling internal state from outside the component.
import { addPropertyControls, ControlType } from "framer"import { motion } from "framer-motion"import { useState, useEffect, useLayoutEffect } from "react"
// Learn more: https://www.framer.com/docs
/* * @framerSupportedLayoutWidth auto * @framerSupportedLayoutHeight auto */export default function Test(props) { const { start = 3 } = props const [count, setCount] = useState(0) useLayoutEffect(() => { if (start !== count) setCount(start) }, [start]) return ( <motion.div style={{ ...containerStyle }} onClick={() => { setCount(count + 1) }} > {new Array(count).fill(1, 0, count).map((_, index) => { return <motion.div style={squareStyle}>{index}</motion.div> })} </motion.div> )}
addPropertyControls(Test, { start: { title: "Start", type: ControlType.Number, defaultValue: 2, },})
const containerStyle = { display: "flex", justifyContent: "center", alignItems: "center", overflow: "hidden",}
const squareStyle = { margin: 10, padding: 50, color: "white", fontWeight: 600, borderRadius: 25, backgroundColor: "#09F", width: "max-content", whiteSpace: "pre-wrap", flexShrink: 0,}
#Height/Width Values
Sometimes when writing components you may want to know the size of the component in pixels. To do this you will need to measure the component with a resizeObserver, however, you should try to avoid this if possible as there is a performance impact for each component that measures itself.
Here is an example using a helper hook to get these values. This example is a component that sizes normally when fixed sizing is enabled, but when auto-sizing is enabled for the height, the height becomes 50% of the width value at all times.
import { useMeasuredSize } from "https://framer.com/m/framer/useMeasuredSize.js"
/*** @framerSupportedLayoutWidth fixed* @framerSupportedLayoutHeight any*/export function ScaledToggle(props) { const { tint, onTap } = props const container = useRef<HTMLDivElement>() const size = useMeasuredSize(container) const width = size?.width ? size.width : 50 const height = size?.height ? size.height : 50
return ( <motion.div initial={false} ref={container} animate={{ backgroundColor: tint }} style={{ width: 50, height: width * 0.5, ...style }} /> )}