Yes, I’m aware that it’s still in beta. But as it stands right now, Figma Sites are a clear path to creating an incredible mess of a site. If you look at just a tiny microcosm of the code in the launch demo for Figma Sites, it’s obvious that the code does not even tip a hat in the direction of semantics.
Here’s a single link in the “top” navigation of the page (quotes are intentional):
<div role="link" tabindex="0" href="https://www.figma.com/contact/?utm_source=figma&utm_medium=sites&utm_campaign=recap" target="_blank" rel="noreferrer noopener" class="css-134pm3 css-pygvzv css-5knerd" style="opacity: 1;">
<div class="css-trglf0 css-r0azwh" style="background-color: rgba(255, 255, 255, 0.16); opacity: 1;"></div>
<div class="css-gxdil1 css-g0vp85 css-j9f0op">
<div class="css-atqysq css-paq0kv css-pygvzv">
<div class="textContents css-wc1msa css-4zzvf5 css-4plp06" data-paragraph-spacing="0px" data-list-spacing="0px" style="color: rgb(255, 255, 255); font-size: 32px; font-weight: 400; letter-spacing: -0.96px; line-height: 0; opacity: 1; transform: none; transform-origin: 50% 50% 0px;">
<div class="css-8zr56v css-ys2p7u css-e3ep6k" aria-label="Contact sales">Contact sale<span class="css-yrwjsr css-ftm40m">s</span></div>
</div>
<div class="textContents css-wc1msa css-4zzvf5 css-4plp06" data-paragraph-spacing="0px" data-list-spacing="0px" style="color: rgb(255, 255, 255); font-size: 32px; font-weight: 400; letter-spacing: -0.96px; line-height: 0; opacity: 1; transform: none; transform-origin: 50% 50% 0px;">
<div class="css-8zr56v css-ys2p7u css-e3ep6k" aria-label="Contact sales">Contact sale<span class="css-yrwjsr css-ftm40m">s</span></div>
</div>
</div>
</div>
<div class="css-trglf0 css-ggwoeh css-s3s1qq" style="border-width: 0.601136px; border-color: rgba(0, 0, 0, 0); border-style: solid; opacity: 1;"></div>
</div>
What’s in a link? (Well, this link, specifically.)
This is an impressive amount of code for a single link. But let’s discard the junk code, and just take a look at the parts of it that are actually problems for users. Afterall, as much as a dozen nested div
elements are messy, wasteful, and unnecessary…they have minimal impact on the user.
The “top” navigation
First item is that this whole top navigation container is located near the end of the document, after the footer
element. So from the very beginning, we’re in a situation where the so-called main navigation is way out of any expected position.
The “link”.
Notably, this is not an anchor element. This is a div
with role="link"
and tabindex="0"
. So it will be keyboard navigable, and it does report as a link. However, it’s controlled entirely with Javascript, and in my testing the events didn’t fire on any keypress. So for a keyboard user, it’s basically a non-event. It does fire for screen reader users (in theory, and in the single test I performed), because screen readers simulate click events.
The accessible name.
Screen readers can use the link – but you may notice that the text of this link appears several times in the code. Four times, to be specific. There are two div
elements inside the link, and both have an aria-label
with the value “Contact Sales” and inner text with the text “Contact Sales.”
The aria-label
is basically irrelevant; because it’s not on the interactive element, it’ll pretty much just be ignored.
The duplicate element, however, will *not* be ignored. So the accessible name of this control is “Contact Sales Contact Sales”. Not a blocking problem, but definitely an irritation. Especially given how often it happens here.
The animation.
The link has an animated hover state. (This is what the second div
with the text is accomplishing.) The animation does not respect any reduced animation preferences. Now, this is a sort of subtle navigation; somebody could make a choice that it isn’t enough to require elimination. But given all the other animations on the page, I’m going to operate on the assumption that nobody made that call.
The change of context.
Naturally, this isn’t-really-a-link also opens in a new tab without any warning. And the new tab is on a different site (back home at Figma.com), so getting back where you came from could be tricky, if you’re confused by this change. Thanks for the warning!
The Big Picture
That’s a microscope on just one link on the page. And that one link manages to trigger at least five separate accessibility violations. Let’s just take a super-quick overview of some larger-scale issues:
Headings hierarchy.
It’s sketchy. Two H1 headings, most of the remaining content is also headings.
Images.
This is a very image heavy site; tons of complex images, many with extensive text content, since they’re pictures of user interfaces. How about alternative text? Well, some of them do have alternative text. But honestly, it’s pretty random. At least there is evidence that it’s possible to have alt text.
Structure.
The site does have some landmarks. But they’re super random. There’s a banner
landmark near the top, a navigation
landmark near the bottom, a footer
landmark above the navigation, and no main
landmark. Overall, not structure. You’d be hard-pressed to find your way around this site using landmarks. And the headings aren’t going to help a lot, based on what I mentioned above.
Low Vision.
Let’s try enlarging the text. Now what? Well, at 200%, I’ve lost full visibility of the “top” navigation text. Button design within the content are also starting to lose text. The social media navigation is badly overlapping, and the language switcher is only partially visible. But the bulk of body text is still visible.
Could be worse, definitely could be better.
Speaking of languages…
The site comes with a language switcher to view it in Spanish, French, Portguese, Japanese, and Korean. But the links to switch language are written in the native language, but without a language attribute; and once you’ve switched the site, it still starts with html lang="en"
regardless of the language viewed.
And I just don’t have the words to describe this remarkable custom cursor:
In Summary
It’s honestly hard to tell how many of the problems here come from fundamental flaws in the tool versus problems in the creation process. Was the team creating this under intense time pressures? Probably. But with a lot of these things, a truly smart tool would just not make these mistakes. The order of content should be more easily linearized, so that things at the top of the design are not at the bottom of the page. Objects that are interactive should always be natively interactive elements. Animations should default to respecting prefers reduced motion flags. Images should require decisions about alternative text.
There’s nothing new here outside of the strengths Figma already had. You can generate garbage code with some really useful graphics tools. Before, you could only generate the graphics, and you had to go elsewhere for your garbage code.
Joe Dolson
Yeah, this is output that really allows us to reminisce about the grand old days of HTML (HyperText Markup Language) generation…
“Back in my day, there was no separation between structure and presentation! We had build our websites uphill in the snow, both ways!”
Werner Glinka
After the broad adoption of Tailwind CSS (Cascading Style Sheets), nothing can surprise me anymore.
Paul
That combination of style and class attributes is comical. Reminds me of MS Frontpage or HTML (HyperText Markup Language) generated by MS Word.
ds
What goes around comes around; there’s nothing new under the sun.
Anyone remember Microsoft FrontPage, the dross Word dumped out as HTML (HyperText Markup Language), or Macromedia Dreamweaver’s bloated outputs? Well, here we are again …
Joe Dolson
Thanks, Eric! That’s a good point; I’ll update it.
Eric Eggert
> because screen readers intercept click events.
I think in this context “trigger” or “simulate” instead of “intercept” is easier to understand/closer to what screen readers actually do.