@profpowell/browser-window
v1.4.7
Published
A Safari-style browser window web component for demos and tutorials
Downloads
851
Maintainers
Readme
@ProfPowell/browser-window
A Safari-style browser window web component for demos and tutorials. Features source code viewing, full-screen expand mode, CodePen export, automatic theme detection, and full theming support.
View Documentation | Live Demos | API Reference
Based on @zachleat/browser-window with significant enhancements.
Installation
npm
npm install @profpowell/browser-windowimport '@profpowell/browser-window';CDN
<!-- unpkg -->
<script type="module" src="https://unpkg.com/@profpowell/browser-window"></script>
<!-- jsdelivr -->
<script type="module" src="https://cdn.jsdelivr.net/npm/@profpowell/browser-window"></script>Direct Download
<script type="module" src="path/to/browser-window.js"></script>Usage
Basic Usage
<browser-window url="https://example.com" title="My Demo">
<img src="screenshot.png" alt="Demo screenshot">
</browser-window>Loading External HTML
<browser-window
src="demos/my-demo.html"
url="https://example.com"
title="CSS Demo">
</browser-window>Dark Mode
The component automatically respects your system's prefers-color-scheme preference. You can also explicitly set the mode:
<!-- Follows system preference (default) -->
<browser-window src="demo.html"></browser-window>
<!-- Always light -->
<browser-window mode="light" src="demo.html"></browser-window>
<!-- Always dark -->
<browser-window mode="dark" src="demo.html" shadow></browser-window>Resizable
The component is resizable by default. Drag the bottom-right corner to resize:
<!-- Set initial size with CSS -->
<browser-window src="demo.html" style="height: 400px; width: 600px;">
</browser-window>Iframe Permissions (camera, microphone, built-in AI)
Use the allow attribute to grant Permissions Policy directives to the inner iframe. This is required by Chrome for some APIs — including the built-in AI APIs (window.ai / Gemini Nano) — even when the iframe is same-origin:
<!-- Camera + microphone access -->
<browser-window src="webcam-demo.html" allow="camera; microphone">
</browser-window>
<!-- Chrome built-in AI demo -->
<browser-window src="ai-chat.html" allow="camera; microphone">
</browser-window>
<!-- Fullscreen + referrer control -->
<browser-window src="player.html" allowfullscreen referrerpolicy="no-referrer">
</browser-window>Attributes
| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| url | string | '' | URL to display in the address bar |
| title | string | hostname from url | Title shown in the URL bar |
| src | string | '' | Path to HTML file to load in iframe (enables source viewing) |
| mode | 'light' | 'dark' | auto | Color scheme. Omit to follow system preference |
| shadow | boolean | false | Add drop shadow to the window |
| device | string | '' | Device preset for phone/tablet bezel mode |
| device-color | string | 'midnight' | Bezel color: midnight, silver, gold, blue, white |
| orientation | 'portrait' | 'landscape' | 'portrait' | Device orientation |
| show-safe-areas | boolean | false | Show safe area overlay bands (device mode) |
| allow | string | '' | Permissions Policy directives passed through to the inner iframe (e.g. "camera; microphone"). Required by Chrome for some APIs (built-in AI / Gemini Nano, sensors) even on same-origin frames |
| allowfullscreen | boolean | false | Pass through to the inner iframe to permit Fullscreen API requests |
| referrerpolicy | string | '' | Pass through to the inner iframe (e.g. "no-referrer", "origin") |
Device Presets
| Preset | Device | Screen |
|--------|--------|--------|
| iphone-16 | iPhone 16 | 393 x 852 |
| iphone-16-pro-max | iPhone 16 Pro Max | 440 x 956 |
| iphone-se | iPhone SE | 375 x 667 |
| pixel-9 | Pixel 9 | 412 x 923 |
| pixel-9-pro-xl | Pixel 9 Pro XL | 448 x 998 |
| galaxy-s24 | Galaxy S24 | 360 x 780 |
| ipad-air | iPad Air | 820 x 1180 |
| ipad-pro-13 | iPad Pro 13" | 1032 x 1376 |
| ipad-mini | iPad mini | 744 x 1133 |
Device Mode
Render content inside a realistic phone or tablet bezel:
<!-- iPhone 16 -->
<browser-window device="iphone-16" src="app.html"></browser-window>
<!-- Landscape Pixel 9 with silver bezel -->
<browser-window device="pixel-9" orientation="landscape" device-color="silver" src="app.html">
</browser-window>
<!-- iPad Air with safe area overlays -->
<browser-window device="ipad-air" show-safe-areas src="app.html"></browser-window>Features
Source Code Viewing
When src is set, a code icon appears in the URL bar. Click to toggle between the rendered content and the source code.
Maximize Mode
- Double-click the title bar to maximize/restore
- Click the green button to maximize
- Press Escape or click the overlay to restore
- Maximized windows display as a centered modal with backdrop
Share Menu
When src is set, a share button provides:
- Share... - Native Web Share API (on supported devices)
- Open in CodePen - Export demo to CodePen with HTML/CSS/JS separated
Download
Direct download link for the source HTML file.
Automatic Theme Detection
The component automatically follows your operating system's light/dark mode preference using prefers-color-scheme. Set the mode attribute to override this behavior.
Resizable Container
Drag the bottom-right corner to resize the component. The content area (iframe or source view) automatically adjusts to fill the available space. Resizing is disabled when maximized.
Mobile-Friendly
- Touch-friendly control buttons with proper hit targets (44px minimum)
- Responsive layout that adapts to narrow screens
- URL bar text truncates gracefully on small screens
CSS Custom Properties
All visual aspects can be customized via CSS custom properties:
browser-window {
--browser-window-bg: #ffffff;
--browser-window-header-bg: #f6f8fa;
--browser-window-border-color: #d1d5da;
--browser-window-border-radius: 8px; /* or var(--radius-m) for Vanilla Breeze */
--browser-window-inner-radius: 6px; /* URL bar, buttons */
--browser-window-border-width: 1px;
--browser-window-border-style: solid;
--browser-window-text-color: #24292e;
--browser-window-text-muted: #586069;
--browser-window-url-bg: #ffffff;
--browser-window-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
--browser-window-close-color: #ff5f57;
--browser-window-minimize-color: #febc2e;
--browser-window-maximize-color: #28c840;
--browser-window-accent-color: #2563eb;
--browser-window-hover-bg: #f3f4f6;
--browser-window-content-bg: #ffffff;
--browser-window-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--browser-window-mono-font: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
/* Device mode */
--browser-window-bezel-color: #1a1a1a;
--browser-window-status-bar-color: rgba(255,255,255,0.9);
--browser-window-home-indicator-color: rgba(255,255,255,0.3);
--browser-window-safe-area-color: oklch(0.65 0.2 250 / 0.25);
/* Layout */
--browser-window-margin: 1rem 0;
/* Z-index (for stacking context control) */
--browser-window-z-index: 9999;
--browser-window-overlay-z-index: 9998;
--browser-window-menu-z-index: 1000;
}Custom Theme Example
/* Purple theme */
browser-window.purple-theme {
--browser-window-accent-color: #8b5cf6;
--browser-window-header-bg: #faf5ff;
--browser-window-border-color: #c4b5fd;
}Accessibility
- Full keyboard navigation with visible focus indicators
- ARIA labels on all interactive elements
role="dialog"andaria-modalwhen maximized- Respects
prefers-reduced-motionfor animations - Escape key closes maximized view and menus
- Touch targets meet WCAG 2.1 minimum size requirements
Browser Support
Works in all modern browsers that support Web Components:
- Chrome/Edge 67+
- Firefox 63+
- Safari 13.1+
Note: device scaling relies on ResizeObserver, and source fetching uses AbortController.
Development
# Install dependencies
npm install
# Start development server
npm run dev
# Run linter
npm run lint
# Run tests
npm test
# Build for production
npm run build
# Generate custom elements manifest
npm run analyzeScripts
| Script | Description |
|--------|-------------|
| npm run dev | Start the local Vite dev server (default: port 5173) |
| npm run build | Build for production (JS + types) |
| npm run lint | Run ESLint |
| npm run lint:fix | Run ESLint with auto-fix |
| npm run format | Format code with Prettier |
| npm run test | Run test suite |
| npm run test:ui | Run tests with interactive UI |
| npm run analyze | Generate custom-elements.json manifest |
Related Projects
- <code-block> - Syntax-highlighted code block web component with copy button
- @zachleat/browser-window - The original component this project is based on
License
MIT
