Here’s a cool iframe component that loads fast and is accessible.
If the iframe content is a small HTML demo you control,
the isolated Gatsby demo approach shows a simpler srcdoc
setup.
I’m thinking the iframe (Inline Frame) should have the following things:
- Accessible: easy, because iframes have no major accessibility issues.
- Optional caption: iframes can also be wrapped in
figure. - Lazy loaded: for page speed, easily done with
loading='lazy'. - Fluid width: for responsive layouts.
The React component
For simplicity this component is styled with react style object.
import type { ComponentProps } from 'react'
interface IframeProps extends ComponentProps<'iframe'> {
caption?: string
title: string
}
export function Iframe({
caption,
loading = 'lazy',
style,
title,
width,
...props
}: IframeProps) {
return (
<figure
style={{
margin: '0 0 20px 0',
...(width
? { width }
: {
display: 'flex',
flexDirection: 'column',
overflow: 'hidden',
width: '100%',
}),
}}
>
<iframe
{...props}
loading={loading}
title={title}
style={{
border: '1px solid gray',
flexGrow: 1,
marginBottom: caption ? '3px' : '5px',
padding: 0,
...style,
}}
/>
{!!caption && (
<figcaption style={{ margin: 0, fontSize: '85%' }}>
{caption}
</figcaption>
)}
</figure>
)
}Accessibility
Iframes have no big accessibility issues in general, just remember to provide the title.
...descriptive title attribute value is not required for accessibility, but if the inline frame presents content as a whole that is visually distinctive, such as an advertisement or video player, then a title should be provided to indicate this distinction.
WebAIM
Demo
Usage:
<Iframe
caption='This website’s 404 page loaded into an iframe'
height={520}
sandbox={false}
src='https://intternet.dev/404'
title='404 page example'
/>Results:
Conclusions
Remember not embed dodgy sites, same way you wouldn’t provide a link to a dodgy site. If iframes are used for same-origin URLs, there’s not much to worry about.
You should prevent other sites embedding you site into an iframe, to prevent
clickjacking etc. It can
be done by setting the X-Frame-Options header value to DENY.