Positioning elements
By default, adding an element to the user's design positions the element in the center of the page and scales it to a size that's determined by Canva.
Likewise, elements inside groups and app elements have default positions and scaling.
Apps can, however, override these values to set the position of elements in either context.
How to position elements on a page
The syntax for positioning an element depends on the method that renders the element.
When calling the addElementAtPoint
method (or addElementAtCursor
, depending on the current context), pass the position in with the first argument:
await addElementAtPoint({type: "embed",url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",// Positionwidth: 640,height: 360,top: 0,left: 0,rotation: 0,});
When calling the addOrUpdateElement
method, pass the position in as the second argument:
appElement.addOrUpdateElement({// app element data goes here},{// Positionwidth: 640,height: 360,top: 0,left: 0,rotation: 0,});
In both cases, the following properties must be used together:
width
height
top
left
The rotation
property is always optional, but only has an effect if the positional properties are set.
Using the dimensions of the current page
-
In the Developer Portal, enable the
canva:design:content:read
permission. In the future, the Apps SDK will throw an error if the required permissions are not enabled. To learn more, see Configuring permissions. -
Call the
getCurrentPageContext
method:import { getCurrentPageContext } from "@canva/design";const context = await getCurrentPageContext();console.log(context.dimensions); // => { width: 1280, height: 720 }tsThe method returns a
dimensions
property that you can use to:- Position elements within the bounds of the current page.
- Position elements in relative terms — for example, in the bottom-right corner.
How to position elements in groups and app elements
You can set the position of elements inside groups and app elements, and since app elements are essentially groups with extra features, the approach to positioning elements is the same.
Box model
You can think of an app element and a group as a box.
By default, the box doesn't have a width or height. Instead, the size of the box is based on the size and spacing between the elements it contains.
Dimensions
The elements inside a box must have a width and a height. (The one exception is text elements, which can't have a predefined height.)
When the width is defined as a number, the height can be set to "auto"
(and vice versa). At runtime, Canva replaces "auto"
with a value that maintains the aspect ratio of the element.
Coordinates
Within a box, elements can be positioned with top
and left
coordinates. These coordinates are relative to the box's origin — that is, the top-left corner of the box.
The origin is determined by the box's topmost and leftmost elements. For example, if the topmost element has a top
position of 50
and the leftmost element has a left
position of 100
, then:
- The top and left coordinates of the box start from
50
and100
- The top and left coordinates of all other elements are relative to
50
and100
To illustrate, here's a diagram:
This can be confusing — especially if you're using negative values for positions — so we recommend treating the top
and left
coordinates as 0
and 0
, even though this isn't strictly required.
Spacing
Elements can be positioned to overlap or to have spacing between them. The size of the box grows or shrinks to accommodate for the combined size of the elements.
When elements overlap, the ordering of the elements is determined by the order in which the elements are rendered. The elements later in an array are rendered in front of elements earlier in the array.
Padding
Boxes do not have padding. There's always one element positioned against each edge of the box.
Units of measurement
Within a box, dimensions and coordinates are defined with relative units, not absolute units. This means 200
is always twice as large as 100
, but these numbers don't correspond to pixel values.
The end result is that, if a design is 1920 pixels × 1280 pixels, setting the dimensions of a box's elements to a combined size of 1920 pixels × 1280 pixels will not necessarily result in the box extending to the edges of the design. Instead, the box will be scaled to a size that's calculated by Canva.
How Canva determines the absolute size of elements depends on a variety of factors that may change over time and is beyond the scope of this documentation.
The key takeaway is to never treat dimensions or coordinates within a box as absolute values.
API reference
Code samples
Positioning app elements
import React from "react";import { getCurrentPageContext, initAppElement } from "@canva/design";const appElement = initAppElement({render: () => {return [{type: "embed",url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",width: 640,height: 360,top: 0,left: 0,},];},});export function App() {async function handleClick() {const context = await getCurrentPageContext();if (!context.dimensions) {console.warn("The current design does not have dimensions");return;}const width = 640;const height = 360;const top = context.dimensions.height - height;const left = context.dimensions.width - width;await appElement.addOrUpdateElement({// app element data goes here},{width,height,top,left,});}return (<div><button onClick={handleClick}>Create positioned app element</button></div>);}
Positioning native elements
import React from "react";import { addElementAtPoint, getCurrentPageContext } from "@canva/design";export function App() {async function handleClick() {const context = await getCurrentPageContext();if (!context.dimensions) {console.warn("The current design does not have dimensions");return;}const width = 640;const height = 360;const top = context.dimensions.height - height;const left = context.dimensions.width - width;await addElementAtPoint({type: "embed",url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",width,height,top,left,});}return (<div><button onClick={handleClick}>Create positioned native element</button></div>);}
Positioning elements in groups and app elements
import React from "react";import { addElementAtPoint } from "@canva/design";export function App() {async function handleClick() {await addElementAtPoint({type: "group",children: [{type: "embed",url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",width: 100,height: 100,top: 0,left: 0,},{type: "embed",url: "https://www.youtube.com/watch?v=o-YBDTqX_ZU",width: 100,height: 100,top: 0,left: 100,},],});}return (<div><button onClick={handleClick}>Add group element</button></div>);}