Remember that time when you reluctantly added a weird edge-case, one-off variant to an already too-big component variant set? Or almost did? I do. I hated making that decision! Felt icky. Every solution was a compromise that I didn't want to make... and it always seems to happen with components like <span class="figma-component">◈ Cards</span>. Usually it goes like this:
You drop an instance on the canvas and need to edit the layers. Maybe you have to add layers, or rearrange what’s already there. But you can’t! It’s one of the few things Figma doesn’t let us do: edit the layer structure of instances. But you’ve got deadlines to meet... the thought of detaching comes up.
And POOF! Just like in when Kronk was deciding whether or not to murder llama-Kuzco, your tiny shoulder-devil appears from a cloud of red smoke and says, “hey kid, detaching really is not a big deal unless you make it a big deal—control-option-b, baby! Let’s go, you’ve got work to do!”
POOF! Arriving on your other shoulder is a tiny angel, warning you, “listen, my friend, I promise you are going to regret this. Think of when that ‘component updates available’ toast pops up again and has changes for the very component you’re thinking about detaching. I know you! You’re smart and clever. Surely there’s another way?”
And you do know there's another way...
“Aha!" You proudly announce, "I’ll add another variant to the component set with the layers I need!"
Shoulder devil says, “buddy, you know you’ll hardly ever use this snowflake again, right? You’d really bloat your component library just for this one mockup you’re working on? I’m telling you, detaching is the way.”
“Fine”, you say, “but there’s another solution...”
Your shoulder angel cheers, “I knew you’d figure it out!!”
“I’ll make a separate component!” you declare with confidence, “And I’ll use frames or slash naming or sections to associate it with the original variant set!” You turn to your shoulder devil to say, “This gives me the best of both worlds: the variant set stays slim, and I don’t know to detach. Ha!”
“’Ha!’ is right!” the devil laughs back at you, “listen, I’m on your team. I’m trying to help! So listen when I tell you that making a separate component puts you at risk of misalignment. Just detach. We could’ve handed this off to engineering by now if you had just listened to me the first time!”
The gears in your mind are spinning. There must be a way.
“Okay devil” you say, “Alright. Okay. But I refuse to detach. We’re going old school.”
Shoulder angel gasps, spilling a little popcorn in the process.
“But with a twist! I’m going to use a ◈ Card, hide all the contents, and use absolute positioning to place my content on top of the card!”
Both the angel and devil slap their foreheads in disbelief. “What?! It would work!!!” you exclaim. After a pause, Angel says,
“Okay, now allow me to help you out: what if you used a slot?”
You can feel the lightbulb spark above your head, “Oh! ... yeah that’ll work!”
The name “slot” doesn’t sit right with me (I’ll write another blog post about this later). For now just know when you see me use the word “placeholder” prefixed with a ✂ glyph, I mean what most folks understand as “slots.”
From where I’ve been sitting, ✂ placeholders never really took off the way ⍚ base components did. Which is weird, because like ⍚ bases, ✂ placeholders are immensely powerful. So powerful that the wider design community actually bothered to come up with a word for them (slots)! We should do this more often. Anyway, unlike ⍚ bases, ✂ placeholders are ridiculously cheap workflow boosters for a component library.
Did you know there’s even a <slot> HTML tag called <span class="inline-code">slot</span>? I only just learned that while researching this post! This is a good sign. It means ✂ placeholders in Figma are another way we can use similar building techniques as our engineering counterparts.
✂ Placeholders are made possible in Figma because you can swap any component with any other component. There are no restrictions to this, other than nesting a component inside of itself, because that would create an infinite loop—kind of like holding a mirror up to a mirror. This “no restrictions” thing is key. I remember back in 2017 when I was using Sketch, you could only swap components that shared the exact same dimensions. This was great for things like icons, but it killed any possibility of creating flexible components that could leverage this ✂ placeholder technique for Sketch users (thankfully this is no longer the case for them).
If you’ve suffered through the scenarios I introduced this post with, read on! Below I cover what exactly ✂ placeholders are, best practices, how they pair with the six other types of components, and mistakes to avoid. And boy howdy, are there some big 👏 miss 👏 steaks 👏 that I see folks unknowingly and regularly commit.
✂ Placeholders contain no visual design decisions. Their job is simply to hold space for other components that will eventually replace them. They allow designers to inject custom compositions into instances, effectively "editing" an instance's layer structure. This greatly reduces the component’s complexity, and offers a massive boost in flexibility.
If you run an image-search for “slot” you’ll probably get slot-machines, or coin slots for candy dispensers. In the physical world, slots are empty holes. These holes are typically punched out of very stiff material, like metals (to prohibit tampering), because the slots are meant to accept very specific shapes (like coins).
But in Figma, the ✂ placeholders we use aren’t voids, and they’re not rigid! They’re objects, they show up as layers. They are there. They’re instances of a component! And with auto layout, they have the ability to grow and shrink. That’s why I prefer the name “placeholder.” And that name, “placeholder”, is what makes the ✂ glyph make sense: it suggests this action of “removal”, which is necessary to swap something else in.
◈ Interface reps. take the visual design language of a product's brand and apply it to functional parts of a product, be it a website, mobile app, or software. The name is (purposefully) obvious: these things represent pieces of interface. They're what designers pull out of Figma's asset panel to compose mockups and string together prototypes. They're the "design expression" of what gets referenced by engineers who go on to craft the "code expression" (the real-life components) that get pushed to production.
You'll almost never use a ✂︎ placeholder that doesn’t contribute to an ◈ interface rep. ✂ Placeholders are especially useful for any container-like ◈ interface reps whose content is hard to predict:
With the addition of component properties, working with ✂︎ placeholders has gotten easier than ever! Swapping a nested ✂︎ placeholders can now happen from the parent ◈ interface rep's properties. This means less deep-clicking, which is an important characteristic of highly usable components.
⍚ Base components can help you create strong foundations for ◈ interface reps, especially when you're working on and testing out new ideas. They allow you to create editable, flexible scaffolding and experiment with different versions without the need to make tons of repetitive updates as your ideas evolve.
⍚ Bases and ✂ placeholders are great companions. If you find yourself creating up ⍚ bases to have fine-grain control over things like padding, corner radius, and space between nested elements, you’ll definitely want to mix ✂ placeholder instances into your ⍚ bases. Making a ⍚ base that uses a ✂ placeholder is simple:
✎ Content carriers are concerned with the content a component holds: the type of content, how much content, how that content behaves (e.g. does it break lines or not), and what it looks like (e.g. what type and color styles, what image cropping rules, etc.). Content is injected into them by way of overrides instead of swapping (remember, swapping is a job for ✂︎ Placeholders).
I’ve already talked a lot about how ✂ placeholders work with ✎ Content carriers, so here’s an actual example to illustrate the relationship:
Let’s pretend I work at Coda and I’m helping their design system team build a <span class="figma-component">◈ Callout</span> component. Callouts are colorful blocks that Coda users can add to their docs to draw attention to a chunk of content. Here’s what that looks like for users, in the app:
Callouts aren’t just limited to text, they can contain images, embedded content like tweets, google maps, youtube videos, you name it! The <span class="figma-component">◈ Callout</span> component would be a perfect opportunity to use placeholders.
It would be constructed using a simple auto layout frame with a swappable icon that can optionally be toggled on and off. The ✂ placeholders would sit where the content will go. Other variants might include some their “quick styles” color and icon combinations that they offer. If the design team found it useful, I could even include a <span class="figma-component">✎ CalloutPlainText</span> (Nathan Curtis might call this a “Lockup subcomponent”):
Despite having access to the <span class="figma-component">✎ CalloutPlainText</span> instance, designers will eventually need to put more than a title and paragraph in a callout: like adding in a button below the paragraph. When they grab an instance of <span class="figma-component">◈ Callout</span> and change the ✂ placeholder for <span class="figma-component">✎ CalloutPlainText</span>, can duplicate <span class="figma-component">✎ CalloutPlainText</span>, detach it, and make a local content carrier named <span class="figma-component">✎ Callout_TakeSruvey</span>that includes their button:
Then it's just a matter of swapping that local ✎ content carrier in!
⍂ Starter kits are meant to be detached from their main component. They are simply collections of instances ◈ interface reps, that get used together often. The time-saving aspect is in not having to drag in dozens of tiny individual components from the asset panel, one by one.
I would not include ✂ placeholders inside of a ⍂ starter kit. As stated earlier, ✂ placeholders are pretty cheap to create, and can benefit from being in a monogonous relationship with the ◈ interface rep. that they support.
That’s not to say your ⍂ starter kit should exclude the ◈ interface reps that have ✂ placeholders nested in them though! In fact, I’d expect to see lots of ◈ interface reps + ✂ placeholder combos in a ⍂ starter kits. Here’s another example using Coda:
Coda allows you to represent their table rows as cards. Here's an example where I've taken a "Task" table, turned it into a card view, and am grouping cards by their status:
But the contents of those cards could look like anything! Designers might need progress bars, they might need a People column, and there’s tons of other stuff not displayed: buttons, reactions, checkboxes, toggles, the list goes on!
This is where providing a curated collection of instances—a ⍂ Starter kit—can be a big time saver for designers! Here’s how a ⍂ starter kit might look in a component library.
Doesn't look too great, does it? A stack of text layers and a couple instances... it doesn't need to be pretty though. What's useful about the ⍂ starter kit is instead of grabbing instances one by one out of the asset panel, creating text layers and applying styles to them, designers can simply grab an instance of the ⍂ starter kit, detach it, and then immediately start assembling those objects into local ✎ content carriers to swap into the <span class="figma-component">◈ Card</span>’s placeholder!
That took me about a bit over a minute. I also tried making the same card without a starter kit! I created the text layers and apply styles by hand, grabbed instances like <span class="figma-component">◈ Person value</span> and <span class="figma-component">◈ Progress bar</span> from the asset panel. It took the same amount of time. But I still preferred the ⍂ starter kit method, mostly because I could keep my eyes (and cursor) on the canvas. It felt faster because I didn’t have to make as many “trips” between those major zones of Figma’s interface (left-hand panel, canvas, right-hand panel).
These components are for internal use only. They're not part of the product that designers are building. ✍︎ Annotations exist to help organize and make sense of Figma files. Unlike the other components, ✍︎ annotations are only concerned with file hygiene.
If you’re really serious about your ✍︎ annotations looking sharp, then ✂ placeholders may make sense to introduce. In my opinion you don’t have to be super concerned with the visual design of your ✍︎ annotations, but if you’ve got the time to make them look nice, go for it! Deliveroo's team became 15% more efficient when they started using a dedicated ✍︎ annotation library to improve communication and collaboration for their team in Figma. They’ve generously made this library public as a free downloadable community file! So I took it for a spin to see if there might be opportunities for ✂ placeholders.
Something that caught my eye was Deliveroo’s list components. I think a ✎ content carrier could do well here. At the time of writing this, I see they provide 20 nested list items that can be shown and hidden. Normally I’d say “that’s dangerous!” but for an ✍︎ annotation component, I’m waaaay more relaxed about hidden layers. They’re so lightweight! This makes them pretty safe memory-usage-wise, especially if the layers being hidden are just—
—hold the phone.
Okay, please allow me a brief aside 🙏. When I find myself using absolutes—like I was in that last paragraph, me saying “They’re so lightweight” could be interpreted as “All ✍︎ annotation components are lightweight” (which isn't inherently true)—I try to stop and immediately search for something that will prove me wrong. In this case, I wanted to see if I could find an example of an ✍︎ annotation component that was on the chunky side in terms of layer count. I already had Deliveroo’s library open, so I started investigating their list component I had just dismissed as being pretty safe.
Lo and behold... each list item is 37 layers! What!? Where are all those coming from!? All I see is a checkbox and some text!
Okay. All useful stuff! Fine. Honestly, it’s probably easier to show/hide layers than bother with component swapping. But it all depends on how the team likes to work!
But that’s not to say there won’t ever be an ✍︎ annotation component that couldn’t benefit from a ✂ placeholder! Here’s an example:
Maybe you have a <span class="figma-component">✍︎ component spec stage</span> component that includes some basic elements like a text layer for the component’s name, and another text layer to write about usage guidelines, and then just a ✂ placeholder where you can drop in an instance of the component that needs spec-ing out.
If you ever decide to include other “metadata” layers in your <span class="figma-component">✍︎ component spec stage</span>, or change its visual design, then instances that have already swapped the ✂ placeholder for a component they want to spec out can receive the update without losing that swap override!
The same way we wouldn't not componentize a piece of interface we're using in more than one place, why would we draw the same kind of prototyping noodle more than one? That's what ⎌ Switchboards are for. They're particularly handy for larger prototypes that need to offer an "open world" or free-roaming experience (as opposed to following a scripted pre-defined path of clicks).
I don’t really see a ton of utility with this particular combination. I promise if someone gives me a good example, or if I find one myself, I’ll update this post accordingly.
I’m not too surprised that this combination may be a dud: both ✂ placeholders and ⎌ switchboards are used in very specific contexts (unlike ◈ interface reps, which are the bedrock of everything we do in Figma)!
If you'd like to be notified of when I publish a new blog post, joining my newsletter is a great way to keep up. Right now I'm averaging 1 post every ~3 months (and trying to pick up my pace).