✂ Placeholders are for people who know trying to predict the future is a losing game

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!”

<div class="horizontal-rule"></div>

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, defined

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

Why the “✂” glyph for placeholders?

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.

Best practices for building useful components with ✂ placeholders

  1. Ensure you’ve enabled auto layout! to the following: your ✂ placeholder component, the components that will be using instances of the placeholders (like <span class="figma-component">◈ Card</span>), and any components you may swap placeholders out for (like <span class="figma-component">◈ Card content</span>). Put another way: everything in your component library should be using auto layout. It’s required for ✂ placeholders to work correctly. Otherwise when you go to swap out the ✂ placeholder for other instances, things might not respond to the new dimensions of whatever you swapped in.
  2. Keep your ✂ placeholders unpublished. They're not really necessary to have in the asset panel because it's easy enough to make a local placeholder component in a local file if you ever need one. Add a period <span class="inline-code">.</span> or underscore <span class="inline-code">_</span> to the beginning of your library’s ✂ placeholders to prevent them from being published.
  3. Style your ✂ placeholders to look very out-of-place among the visual design language of the rest of your components. Here’s some ideas to try:

    A) Choose a color or gradient that will easily stand out among the palette you’re using in your actual design work. Vibrant neons, color-wheel inspired rainbows, or murky, muddy browns. Whatever might be the opposite of your product's real color palette! And no need to make this color a style, it’s just for your ✂ placeholders.

    B) If your designs use so many color that you can’t pick one that will make your ✂ placeholders stand out, try textures and images! Rogie’s noise & texture plugin can make a one-of-a-kind fills. Or pick an image from wikipedia, like the main photo from the entry on puppies, ducks, or otters.

    C) Having a hard time finding an image that will stand out? You could try tiling it! Or, if not an image, try tiling the logo of your product or company (kind of like a Getty Images watermark).
  4. Turn on “expose nested instances” of main components using instances of your ✂ placeholder. This will ensure the properties of whatever component you swap in are surfaced. There may be times you decide not to do this, but it’s a good habit to get into.
  5. Offer ✎ content carriers and set them as preferred values! These are another type of component, and also something that Nathan Curtis has a similar idea for (he calls them subcomponents) that he discussed in a fabulous talk at Schema ‘22. Nathan and I may be using different names, but the concept is similar. Something I appreciate about the name “subcomponent” is it helps us know how it relates to other components in the system: it’s a subcomponent, it’s part of something else. Nathan mentioned this in the naming convention he uses with subcomponents, for example, <span class="figma-component">✎ CardMedia</span> is clearly meant to be used in <span class="figma-component">◈ Cards</span>, and only <span class="figma-component">◈ Cards</span>. He’s also gone a step further and identified four discrete types of subcomponents: Extensions, Lockups, Alternatives, and Repeaters. I highly recommend watching his talk about subcomponents if you haven’t yet seen it.
  6. Be thoughtful about how you name your swap properties! My go-to is “Content”, but it really depends on the main component. For example, I have a slot in a <span class="figma-component">◈ sidebar</span> component that displays bank accounts. So I name the property “account rows.” Of course the name doesn’t limit what can swapped in, but it helps designers know what they're expected to swapped in.

    Since my <span class="figma-component">◈ sidebar</span> is expecting specific ✎ content carriers, I might not even use a slot! Instead I could put a ✎ content carrier in there made up of <span class="figma-component">◈ account rows</span>. When folks see that ✎ glyph, they’ll know they can extract that instance, detach it, and add more <span class="figma-component">◈ account rows</span> if they need more than what was originally provided.

    But there may be times where you don’t know what will get swapped in! It could be anything! I find this to happen with <span class="figma-component">◈ Cards</span>, <span class="figma-component">◈ Modals</span>, and <span class="figma-component">◈ Accordions</span>. In these cases, I keep swap property name open ended and unassuming. A name like, “Content” usually works. Even less assuming would be to describe what originally was there: “Slot” or “Placeholder.”

Mistakes to avoid when working with ✂ placeholders

  1. Trying to predict the future. This is a great way to waste time and make a component that is frustrating to use (probably the opposite of what you’re trying to do)! Above is one example of what future-predicting components look like.
    <br>
    <br>This is what Nathan Curtis described this as Slot bento-boxing. And to be clear, bento-boxing your placeholder is a bad thing (which was tough for me to get my mind around because I love a good bento box 🍱 ).
    <br>
    <br>“If it’s bad, why do folks end up doing it?"
    <br>
    <br>My best guess is they’ve been burned by a too-rigid component library. They find out about slots, and think "more is more!" and as they try to bento-box their way to a more customizable, flexible system. They're looking for more customization without ever having to detach. Unfortunately, they won’t see success. In fact, much like the too-rigid system, slot bento-boxing can crush the usability of the component. Imagine all those component swapping properties in the design panel! <span class="inline-code">placeholder 1</span>, <span class="inline-code">placeholder 2</span>, etc... Can they also be shown and hidden? Yes? Okay, well, now you’ve got twice as many properties to deal with. And when you swap in ◈ interface reps or ✎ content carriers, will their properties be bubbled up and exposed too? God help the folks who have to use these instances, because the majority of the time they don't need every slot. That design panel must be a nightmare.
    <br>
    <br>To be fair, it’s not like the <span class="figma-component">❖ Grid</span> component in the screenshot above isn’t doing anything useful. It’s componentizing the space between rows and columns. It’s almost acting like pseudo-spacing token. But because it has a limited number of placeholders, and given the mess we know it’ll cause in the design panel, is that worth it? I don’t think so. In cases where designers need a grid layout like this, I think they are far better off grabbing instances of the ◈ interface reps that they need, putting them in auto layout frames for rows, and then wrapping those rows in another auto layout frame to manage the vertical space. If they’re unsure about the spacing values, they should reference some documentation to get that guidance. Figma, as great as it is, can only do so much. We should not force designers to use convoluted components when we could simply rely on documentation and a bit of manual effort in local files.
  2. Listening to folks who discourage the multi-placeholder approach wholesale.

    “Alice, what the hell, I JUST got done reading your whole rant about bento-boxing and how you’re sa—”


    I know, bear with me, I’ll explain:

    Trying to predict every possible way designers might want to customize a component using placeholders is what wastes time. That’s like trying to look into a crystal ball and predict the future, and it’s how you get into bento-box-mode. However, providing strategic, thoughtful, and opinionated placeholders, (that’s right, plural, “placeholders”) that are based in the reality of your team’s needs today, is an excellent thing to do. Talking with your component users is the key to making usable components.

    How many placeholders you provide is all about how much freedom or control you want to offer to designers using instances of that component (hmm maybe a better way to put that might be: it’s all about how much freedom or constraint your designers want from the system). In that same Nathan Curtis talk (yes, I know this is my third time referencing it lol. It's that good!) he’s taken the idea of ✂ placeholders even further by identifying 4 distinct types that he calls “containers”: blocks, zones, slots, and substitutions.
  3. Not offering ✎ content carrier components when designers need some flexibility but don't want to tediously build from scratch. And you can make it really easy for designers to access those subcomponents by setting them as “preferred” swaps!
  4. Not encouraging designers to create their own ✎ content carrier components in their local files to swap in place of your ✂ placeholders. Remember, the value placeholders bring to your system is liberating it from having to have all the answers for all possible things designers could build. Components that get added to a component library are often born in local files, which means one of the most important jobs of a component library is to make exploration easy. Offering ⍂ starter kits (more on this below) is a great way to do this. These kits are meant to be detached, and can be re-componentized to form local ✎ content carriers.

Pairing with other types of components

<h3 id="interface-rep">✂ placeholders + ◈ Interface representatives</h3>

◈ 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:

  • Cards
  • Modals and pop-ups
  • Table cells
  • Accordions
  • Drawers

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.

<h3 id="bases">✂ placeholders + ⍚ Bases</h3>

⍚ 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:

  1. Create or grab and instance of a ✂ placeholder.
  2. Wrap it in an auto layout frame (shortcut: <span class="inline-code">⌘ + A</span>).
  3. Adjust the ✂ placeholder’s resizing settings appropriately in anticipation of the components you'll be swapping in.
  4. Turn the frame into a main component and 💥 boom. You've got a ⍚ base component to control padding. Consider naming it something like <span class="figma-component">⍚ padding</span>.

<h3 id="content-carriers">✂ placeholders + ✎ Content carriers</h3>

✎ 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:

Example GIF of Coda's "Callout" feature from their documentation

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!

<h3 id="starter-kit">✂ placeholders + ⍂ Starter kits</h3>

⍂ 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).

<h3 id="annotation">✂ placeholders + ✍︎ Annotations</h3>

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!

Ooooohhhhhh

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!

<h3 id="switchboard">✂ placeholders + ⎌ Switchboards</h3>

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)!

Main takeaways

  1. Don’t waste yours or your fellow designers time trying to predict the future by bento boxing your ✂ placeholders. When you need more than one ✂ placeholder in an ◈ interface rep, make sure you have a strong reason for why a single ✂ placeholder wasn’t enough. A red flag to watch out for is if you’re picking an arbitrary number of ✂ placeholders, or thinking “hmm better add another, just in case.”
  2. A better way to frame the “never use multiple ✂ placeholders” advice is this: trading a single slot for a single component is rarely worth it. Instead, trade placeholders for a collection of components and layers. Again, you may have a great reason to offer more than one ✂ placeholder! You know your system and your team’s needs better than strangers on the internet.
  3. Keep a close watch for objects you find yourself using over and over to compose ✎ content carriers you create to swap in for your ✂ placeholders. This is a clue that you may have found good candidates for a ⍂ starter kit or subcomponent that you ought to publish from your component library.