A good[ish] website
Web development blog, loads of UI and JavaScript topics
Here’s a cool iframe component that loads fast, is accessible, and easy on the eyes.
I’m thinking the iframe (Inline Frame) should have the following things:
<figure>
.See the highlighted lines and the breakdown below.
import React from 'react'
import PropTypes from 'prop-types'
import { Iframe, Figure, Figcaption } from './styles'
const IframeComponent = props => {
const { caption, width } = props
return (
<Figure width={width}> <Iframe {...props} frameBorder={0} hasCaption={Boolean(caption)} />
{caption && <Figcaption>{caption}</Figcaption>}
</Figure>
)
}
const srcPropsCheck = (props, propName, componentName) => { if (!props.src && !props.srcDoc) {
return new Error(
`One of 'src' or 'srcData' is required by '${componentName}' component.`
)
}
}
IframeComponent.defaultProps = {
loading: 'lazy', height: 500,
sandbox: ''}
IframeComponent.propTypes = {
caption: PropTypes.string,
height: PropTypes.number,
loading: PropTypes.oneOf(['lazy', 'eager']), sandbox: PropTypes.string,
src: srcPropsCheck,
srcDoc: srcPropsCheck, title: PropTypes.string.isRequired, width: PropTypes.number
}
export default IframeComponent
Here’s the interesting bits:
Figure
figure
element can be there even if caption is not provided, it’s valid HTML. It also serves as a flex wrapper for the fluid width iframe.srcPropsCheck
PropTypes
helper can take a custom validation function, this checks thatsrc
or srcdoc
are passed in.loading: 'lazy'
sandbox
srcDoc
srcDoc
is used src
can be skipped.title
I’s using styled-components in this case, but there’s nothing special here that wouldn’t work with vanilla CSS or another CSS-in-JS lib:
import styled from 'styled-components'
export const Figure = styled.figure(props => ({
margin: '0 0 20px 0',
...(props.width ? { width: props.width }
: {
display: 'flex',
flexDirection: 'column',
overflow: 'hidden',
width: '100%'
})
}))
export const Figcaption = styled.figcaption({
margin: 0,
fontSize: '85%',
})
export const Iframe = styled.iframe(props => ({
border: '1px solid gray',
flexGrow: 1, marginBottom: props.hasCaption ? '3px' : '5px',
padding: 0
}))
props.width
flexGrow: 1
Good thing is that there are no big accessibility issues with iframes, 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
There’s not too much to demo, but here’s an iframe from this website:
<Iframe
caption="This website’s 404 page loaded into an iframe"
height={520}
sandbox={false}
src="https://clubmate.fi/404"
title="404 page example"
/>
It adapts nicely to the page width:
There’s some amount of mysticism around the safety of iframes, just 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.
The irony of iframes is that you should block other sites from embedding your site, to prevent clickjacking etc. It can be done by setting the X-Frame-Options
header value to DENY
.
Comments would go here, but the commenting system isn’t ready yet, sorry.