Anatomy of a React component
My vision for how every React component should look
421
8 min.
SSI defines requirements for image formats, text alternatives, dimensions, and loading in web interfaces.
SVG
Inline SVG is suitable for small static icons that need to be styled as part of the interface. In Tailwind projects, shrink-0 prevents an icon from shrinking inside a flex or grid container. currentColor lets it inherit the text color:
<svg
class="shrink-0"
fill="none"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
focusable="false"
>
<path d="M12 2L..." fill="currentColor" />
</svg>Informative SVGs, whether static or managed in an admin interface, should be rendered with <img> or next/image and given a meaningful alt. Keeping the SVG as a separate resource also lets the browser cache it.
An inline SVG that only repeats a visible label or decorates the interface should be hidden from screen readers with aria-hidden="true". A meaningful standalone SVG should have role="img" and an accessible name provided by <title> and aria-labelledby.
Untrusted SVG from an admin interface should not be inserted into the DOM as markup. When inline embedding is necessary, the file should pass through a trusted sanitization pipeline. Browsers restrict active content when SVG is used as an image; upload validation is still required.
Raster images
A suitable source image and formats supported by the target environment should be selected. WebP or AVIF can be used for delivery; manual format selection should include a JPEG/PNG fallback in <picture> when required by supported browsers.
A single compression quality should not be used for every image. Quality should be chosen based on visual inspection and file size.
<picture>
<source srcset="/images/photo.avif" type="image/avif" />
<source srcset="/images/photo.webp" type="image/webp" />
<img
src="/images/photo.jpg"
width="1600"
height="1067"
alt="A bicycle beside a brick wall"
/>
</picture>With Next.js Image Optimization, output formats are configured in Next.js. The next/image component generates responsive variants through srcset; <source> elements inside <picture> are used separately when different files or art direction are required.
Informative images should have a concise alt that conveys their meaning in the page context. Generic labels such as “Photo” and repetition of nearby text should be avoided.
Decorative images require an empty alt — alt="". Omitting the attribute can cause a screen reader to announce the file name.
When an image is the only content of a link or button, its alt must communicate the link’s purpose or the button’s action.
An icon-only button should have an accessible name on the button itself, for example through a visible label or aria-label; an SVG icon alone does not name the control.
Important data in charts, diagrams, and other complex images should also be provided in an accessible text format.
<figure> and <figcaption> are appropriate when an image needs a visible caption.
<figure>
<img
src="/images/photo.webp"
width="1200"
height="800"
alt="A bicycle beside a brick wall"
/>
<figcaption>The workshop accepts bicycles for repair by appointment.</figcaption>
</figure>The width and height attributes define an image’s intrinsic dimensions. The browser uses their aspect ratio to reserve space before the image loads and reduce cumulative layout shift (CLS). CSS controls the rendered size.
object-cover is appropriate when an image should fill a box by cropping. With fill, the container needs positioning and dimensions, for example position: relative and aspect-ratio. Important details should remain visible after cropping.
The sizes value must match the image width in the layout. It helps the browser choose an appropriate resource from srcset; sizes does not create image variants by itself. In plain HTML, sizes should be paired with srcset:
<img
src="/images/photo-960.webp"
srcset="
/images/photo-480.webp 480w,
/images/photo-960.webp 960w,
/images/photo-1600.webp 1600w
"
sizes="(max-width: 768px) 100vw, 50vw"
width="1600"
height="1067"
alt="A bicycle beside a brick wall"
loading="lazy"
/>Responsive styles in next/image also require a correct sizes value. It is required with fill, and the parent element must define the image area:
<div className="relative aspect-[3/2]">
<Image
src="/images/photo.webp"
alt="A bicycle beside a brick wall"
fill
sizes="(max-width: 768px) 100vw, 50vw"
className="object-cover"
/>
</div>loading="lazy".loading="eager" is appropriate and fetchPriority="high" can be added when supported by measurement.<img> loads eagerly by default. Lazy loading requires an explicit loading="lazy" attribute; the browser begins fetching the image as it approaches the viewport.next/image uses lazy loading by default unless it is overridden. The rendered markup and component settings should be checked for critical images.Static files can be grouped by purpose. Images managed through a CMS usually remain in the CMS or its connected storage.
public/
├─ icons/ # Static SVG files used with <img>
└─ images/ # Static raster images
src/
└─ shared/
└─ icons/ # Reusable SVG componentsImage verification with Lighthouse and browser DevTools should cover:
alt text, and decorative images use alt="";width and height, or a defined aspect ratio, reserve space before loading;srcset candidate, and sizes matches the actual layout;Informative image with reserved aspect ratio:
<img
src="/images/photo.webp"
width="1200"
height="800"
alt="A bicycle beside a brick wall"
loading="lazy"
/>Informative SVG as a separate resource:
<img src="/icons/user.svg" width="24" height="24" alt="User profile" />Responsive image with source variants:
<img
src="/images/photo-960.webp"
srcset="/images/photo-480.webp 480w, /images/photo-960.webp 960w, /images/photo-1600.webp 1600w"
sizes="(max-width: 768px) 100vw, 50vw"
width="1600"
height="1067"
alt="A bicycle beside a brick wall"
loading="lazy"
/>Critical image in the initial viewport:
<Image
src="/images/hero.webp"
width={1600}
height={900}
alt="A bicycle workshop with a workbench by the window"
loading="eager"
fetchPriority="high"
sizes="(max-width: 768px) 100vw, 50vw"
/>My vision for how every React component should look
421
8 min.
The SST standard defines requirements for the semantics, accessibility, and logic of tabs
62
7 min.
The SSF-U standard defines requirements for the semantics, accessibility, and logic of fullscreen
248
2 min.
The SSA standard defines requirements for the semantics, accessibility, and logic of accordion
258
2 min.
An Analysis of Critical Web Design Mistakes. Why Sliders, Autoplay, and Slow-Loading Pages Reduce Conversion Rates and Rankings on Google
232
2 min.
The SSP standard defines requirements for the semantics, accessibility, and logic of pagination
240
1 min.