On September 25th, 2024, we released v2 of the Apps SDK. To learn what’s new and how to upgrade, see Migration FAQ and Migration guide.

Positioning elements

How to arrange elements in a user's design.

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.

Our design guidelines help you create a high-quality app that easily passes app review.

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",
// Position
width: 640,
height: 360,
top: 0,
left: 0,
rotation: 0,
});
TS

When calling the addOrUpdateElement method, pass the position in as the second argument:

appElement.addOrUpdateElement(
{
// app element data goes here
},
{
// Position
width: 640,
height: 360,
top: 0,
left: 0,
rotation: 0,
}
);
TS

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

  1. 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.

  2. Call the getCurrentPageContext method:

    import { getCurrentPageContext } from "@canva/design";
    const context = await getCurrentPageContext();
    console.log(context.dimensions); // => { width: 1280, height: 720 }
    TS

    The 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.

Some types of designs, such as whiteboards(opens in a new tab or window), don't have dimensions. In these cases, the dimensions property will be undefined.

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.

You can't set both the width and height to "auto". At least one value must be a number.

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 and 100
  • The top and left coordinates of all other elements are relative to 50 and 100

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>
);
}
TSX

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>
);
}
TSX

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>
);
}
TSX