Device Frame Web Component
A customizable web component that renders an iframe inside a mobile device frame, with options for device selection, orientation, folding, and scaling.
Installation
You can install the Device Frame component via NPM or download it manually.
NPM Installation
Install the package using NPM:
npm install @dustinpoissant/device-frame
Then include the minified script in your HTML:
<script type="module" src="node_modules/@dustinpoissant/device-frame/DeviceFrame.min.js"></script>
Manual Download
Download DeviceFrame.min.js directly from the repository and include it in your project:
<script type="module" src="DeviceFrame.min.js"></script>
Attributes
| Attribute | Description | Default |
|---|---|---|
src |
The URL to load in the iframe | false |
device |
Device type (e.g., iphone15promax, galaxys22ultra) | "iphone15" |
controls |
Comma-separated list of controls to show (device, orientation, fold, scaled) | "" |
orientation |
Device orientation (portrait/landscape) | "portrait" |
scaled |
Scales device to fit 80% of viewport | false |
devices |
Comma-separated list of device keys to show in device picker (leave empty to show all) | "" |
Available Devices
- iPhone 15 Pro Max
- iPhone 15 Pro
- iPhone 15
- iPhone SE
- Galaxy S22 Ultra
- Galaxy S22+
- Galaxy S22
- Galaxy Tab S9
- Galaxy Tab A8
- Pixel 8
- Pixel Fold
- Galaxy Z Fold5
- Pixel Tablet
- iPad Pro 12.9"
- iPad Pro 10.5"
- iPad Air 4
- iPad 10.2"
Examples
Basic Device Frame
<device-frame src="https://websiteipsum.com/index.html"></device-frame>
With Device Picker
<device-frame src="https://websiteipsum.com/index.html" controls="device"></device-frame>
Limited Device Options
<device-frame src="https://websiteipsum.com/index.html" devices="iphone15,galaxys22ultra,ipadpro12" controls="device"></device-frame>
With Orientation Control
<device-frame src="https://websiteipsum.com/index.html" device="galaxys22ultra" orientation="portrait" controls="orientation"></device-frame>
With All Controls
<device-frame src="https://websiteipsum.com/index.html" device="pixelfold" controls="device,orientation,fold,scaled"></device-frame>
JavaScript API
You can control the component programmatically in several ways:
Creating Instances Programmatically
You can create device frame elements dynamically in two ways:
Using the Constructor
import DeviceFrame from './DeviceFrame.js';
// Create with constructor
const frame = new DeviceFrame({
src: 'https://example.com',
device: 'iphone15',
controls: 'device,orientation'
});
document.body.appendChild(frame);
Using document.createElement
// Create a new device frame element
const frame = document.createElement('device-frame');
frame.src = 'https://example.com';
frame.device = 'iphone15';
frame.controls = 'device,orientation';
// Add it to the DOM
document.body.appendChild(frame);
Controlling Existing Elements
Control device frames that are already in the DOM:
const frame = document.querySelector('device-frame');
// Set properties
frame.src = 'https://new-url.com';
frame.device = 'galaxys22ultra';
frame.devices = 'iphone15,galaxys22ultra,ipadpro12'; // Limit device options
frame.orientation = 'landscape';
frame.controls = 'device,orientation';
// Get current values
console.log(frame.device); // 'galaxys22ultra'
console.log(frame.orientation); // 'landscape'
Adding Custom Devices
Extend the device library with custom devices:
import DeviceFrame from './DeviceFrame.js';
// Add a custom device
DeviceFrame.devices['customphone'] = {
name: 'Custom Phone',
resolution: [400, 800],
topFrameSize: 20,
bottomFrameSize: 20,
sideFrameSize: 15,
innerRadius: 10,
outerRadius: 15
};
// Now 'customphone' will appear in device pickers
Event Handling
Listen for component changes:
const frame = document.querySelector('device-frame');
frame.addEventListener('devicechange', (event) => {
console.log('Device changed to:', event.detail.device);
console.log('Previous device:', event.detail.previousDevice);
});
frame.addEventListener('orientationchange', (event) => {
console.log('Orientation changed to:', event.detail.orientation);
});
frame.addEventListener('controlschange', (event) => {
console.log('Controls changed to:', event.detail.controls);
});
frame.addEventListener('scalechange', (event) => {
console.log('Scaled changed to:', event.detail.scaled);
});
frame.addEventListener('deviceschange', (event) => {
console.log('Device list changed to:', event.detail.devices);
});
frame.addEventListener('load', (event) => {
console.log('Iframe loaded:', event.detail.src);
// Access the iframe directly
const iframe = event.detail.iframe;
// Or use the getter
const iframe2 = frame.iframe;
});
Iframe Access
Get direct access to the iframe element for advanced use cases:
const frame = document.querySelector('device-frame');
const iframe = frame.iframe;
// Post messages to the iframe
iframe.contentWindow.postMessage('Hello from parent!', '*');
// Listen for messages from the iframe
window.addEventListener('message', (event) => {
if (event.source === iframe.contentWindow) {
console.log('Message from iframe:', event.data);
}
});
Styling
The select controls inherit styles from the page. Use CSS custom properties to customize spacing:
Inline Styles
For a single component, use inline styles:
<device-frame src="https://example.com" controls="device" style="--spacer: 2rem;"></device-frame>
CSS Targeting
Use the CSS Custom Property --spacer to adjust the space between the controls and the device frame.
Target all device-frame components:
device-frame {
--spacer: 2rem;
}
Or target a specific instance:
<device-frame src="https://example.com" class="my-device-frame" controls="device"></device-frame>
.my-device-frame {
--spacer: 2rem;
}