HTML, CSS & JavaScript Playground and Error Checker
Build a small webpage in your browser. Write HTML for structure, CSS for design, and JavaScript for behaviour, then check common errors and run the result in a restricted preview.
Run code carefully. Run only code that you understand or trust. The preview is restricted, but it is not a malware-analysis environment, and JavaScript that never finishes can still make this browser tab unresponsive. Browser sandboxing also cannot stop every hostile request attempt; for example, code may try to replace its own preview frame.
Local learning workspace
Build, check, and run a small webpage
Static checks never execute JavaScript. Only “Run all code” executes the JavaScript editor.
○Editors are ready to be enhanced
Before running JavaScript: Code that never finishes can make this tab unresponsive. Save other work before running code you do not understand.
Copy combined HTML and Download HTML remove the same restricted external-resource markup as the preview. The saved file runs its JavaScript as a normal local page when opened, not inside Foxger’s iframe sandbox. Open downloaded code only when you understand or trust it.
Module syntax is allowed in module mode. External imports and npm packages remain unavailable.
Code editors
HTML is body markup. Put styles and scripts in their matching editors.
0 characters
Enter body content only. Complete document import is available below.
0 characters
External stylesheets are blocked. Write ordinary browser CSS here.
0 characters
JavaScript runs only after you select “Run all code”. Use Ctrl/Cmd + Enter to run.
Preview
HTML and CSS have not been previewed yet.
Preview fits the available panel width.
Checks and runtime feedback
Problems are static findings. Console messages come from the running preview.
Select “Check code” to inspect all three editors without executing JavaScript.
No runtime messages yet. Run all code to start a fresh preview.
Paste a complete HTML document
Foxger can separate body markup, inline CSS, and ordinary inline JavaScript. The local import is conservative and is not a lossless round trip. It never runs imported code automatically.
Keyboard shortcuts: Ctrl/Cmd + Enter runs all code. Ctrl/Cmd + Shift + Enter checks code.
Step-by-step beginner guide
Make the sample button work, then learn why
You have three editors and one small webpage. Start by making its button change a message. The HTML, CSS, JavaScript, and error terms will make more sense after you have seen the page work.
The included page shows My First Webpage, a welcome message, and a button. CSS turns those plain parts into a centred white card. JavaScript makes the button replace the welcome message with The JavaScript worked!
HTML→ what is on the page
CSS→ what it looks like
JavaScript→ what it does
That three-part description is simplified, but it is a useful first model. The same sample carries the rest of the beginner path, so you will not have to decode a new project in every section.
Get an early success
Load the example and see it work
Select Load example. The three editors fill with code, and the HTML/CSS preview appears without running JavaScript.
Look at the preview. You should see My First Webpage, the welcome message, and a Change message button.
Select Preview HTML & CSS. Press the page’s button. Nothing changes yet because the JavaScript editor was not executed.
Select Run all code. Press Change message inside the fresh preview.
The message should now read The JavaScript worked! You have already used the central workflow: preview structure and appearance, then run behaviour deliberately.
One idea: structure
HTML makes the page structure
This is the exact HTML loaded by the example:
<main class="card">
<h1>My First Webpage</h1>
<p id="message">Welcome to my page.</p>
<button id="change-message" type="button">Change message</button>
</main>
Element
<h1>My First Webpage</h1> is a heading element.
Opening and closing tags
<p> starts the paragraph; </p> ends it. The words between them are its text.
Class
class="card" gives CSS a reusable name for the outer main element.
ID
id="message" and id="change-message" give JavaScript exact elements to find. Each ID should be unique.
Button type
type="button" states that this button is an ordinary button rather than an accidental form submit control.
The normal HTML editor is for markup that belongs inside a page’s body. Put styles in CSS and scripts in JavaScript; Foxger reports and removes <style> and<script> elements from preview HTML. Complete-document import can wait until the advanced path.
One idea: appearance
CSS changes what the page looks like
The example’s CSS centres the card, adds spacing, and sets its colours:
A property and value form a declaration. The colon separates them, and the semicolon ends the declaration.
Braces
The opening and closing braces hold the declarations for one rule.
Before trying it, predict the result of changing #f3f4f6 tolightblue. Only the area behind the card should change. Make the edit, then use Preview HTML & CSS if automatic preview is off.
One idea: behaviour
JavaScript makes the button do something
This is the exact JavaScript loaded by the example:
Find the button with querySelector("#change-message").
Find the paragraph with querySelector("#message").
Listen for a click with addEventListener().
Replace the message through its textContent property.
const creates the variables named button and message. An event is something that happens, such as a click. You do not need deeper DOM terminology to use this pattern yet: find → listen → change.
JavaScript does not run automatically after an edit. Foxger marks the script as changed and waits for Run all code, giving you a chance to review it before execution.
Use the whole core workflow
Change, check, break, and fix the page
You have seen each language once. Now use the same page to make two safe changes and repair one deliberate mistake. The sequence has nine meaningful steps rather than a tour of every control.
Return to the starting example
Action: Copy work you need, then select Load example.
Reason: A known working page makes each change easy to recognise.
Expected result: The card appears in Preview, while its JavaScript is ready but has not run.
Change the heading
Action: In HTML, replace “My First Webpage” with “Science Club” between the h1 tags.
Reason: This changes page content without changing its style or behaviour.
Expected result: Automatic preview shows the new heading after a short pause.
Predict one CSS result
Action: Predict what replacing #f3f4f6 with lightblue will change, then edit it.
Reason: The declaration belongs to body, so it changes the area behind the white card.
Expected result: The page background becomes light blue; the card remains white.
The deliberate missing parenthesis appeared in Problems before the script ran. That context makes the two panels easier to separate.
Problems
Starts with findings Foxger can produce by examining the source.
an unclosed HTML tag
a broken CSS declaration
a JavaScript syntax error
After JavaScript runs, captured runtime failures also appear here so you can select their source location when one is available.
Console
Shows messages and failures from the running preview.
console.log(), info(), warn(), error(), and debug()
runtime errors such as ReferenceError or TypeError
unhandled promise rejections
Problems can be filtered by language and by Error, Warning, or Information. Errors come first, followed by warnings and information, then language and source position. Foxger keeps the combined list to at most 500 visible diagnostics and explains when more are hidden.
Clear console removes its visible entries; Copy console output copies their bounded text. The Console is a report, not a command prompt.
The syntax is valid. It fails only after execution because the selector returned null. Inspect Console.
Logic mistake
message.textContent = "Welcome to my page.";
This runs, but it keeps the old message when the intended result was new text. A person normally has to notice the mismatch.
Static syntax mistakes are often detectable. Runtime failures can be captured only when the code runs. A logic mistake can produce no error at all because Foxger does not know what you intended.
Read the line and column after you have a problem
A line is the numbered row. A column is the approximate character position on that row. Select a Problem to open its editor, move the cursor near that location, and scroll it into view. Runtime locations can be less exact because Foxger builds a temporary preview document and labels user code foxger-user-code.js.
Choose what should execute
Preview HTML & CSS versus Run all code
Preview HTML & CSS
builds a fresh restricted preview
uses current HTML and prepared CSS
does not execute the JavaScript editor
is useful while changing content or layout
Run all code
builds another fresh restricted preview
executes the current JavaScript
starts a fresh Console
requires JavaScript syntax errors to be fixed first
Automatic HTML and CSS preview is enabled by default and refreshes after a short pause. It still omits the script: JavaScript does not run automatically. After a JavaScript edit, read the preview status. Foxger marks the displayed behaviour as stale until you choose Run all code again.
Interpret a clean result carefully
What Foxger checks—and why broken code may still appear
HTML
HTMLHint and Foxger check selected fragment issues: paired tags, duplicate IDs or attributes, image alt text, button types, empty sources, obsolete tags, misplaced scripts or styles, inline handlers, and restricted elements.
The editor is body-fragment oriented, so it does not require a doctype, html, head, title, or viewport element. This is not complete standards or accessibility validation.
CSS
CSSTree parses with source positions, recovers from some mistakes, and checks many property names, declaration values, braces, empty rules, and at-rule preludes.
Custom-property values and vendor-prefixed properties are handled cautiously. A clean result does not prove browser support or visual correctness.
JavaScript
Acorn parses current standard JavaScript using the selected Classic script or ES module source type. Classic script is the default.
It checks syntax without execution. It is not ESLint, a type checker, or a test of runtime behaviour and program logic.
Why Preview and Problems can disagree
HTML: browsers repair some incomplete markup into a usable document.
CSS: browsers can ignore an invalid declaration and keep the rest of a rule or stylesheet.
JavaScript: valid syntax can still fail at runtime or do the wrong thing.
A visible page is useful evidence, not proof of correctness. Check the source, run the behaviour, read Console, and compare the result with your intention.
Optional workspace controls
Arrange and edit code when you need more room
Tabs, Show all editors, and responsive panels
Tabs show one code editor at a time. Show all editors displays HTML, CSS, and JavaScript together on wider screens. On mobile, the panel tabs switch between the three editors, Preview, Problems, and Console. Arrow keys, Home, and End move through tab controls.
CodeMirror editing help
The enhanced editors provide line numbers, language syntax highlighting, search, undo/redo history, bracket matching, indentation help, and HTML tag completion. Long-line wrapping is on by default and can be turned off. The editor colours follow Foxger’s System, Light, or Dark theme.
Classic script and ES module
Classic script is the default and suits the sample. ES module mode allows standard module syntax such as export. External imports still cannot load, and the Playground does not provide npm, React, JSX, TypeScript, Sass, or a compilation step.
Shortcuts, preview sizes, copy, reset, and clear
Ctrl/Cmd + Enter runs all code; Ctrl/Cmd + Shift + Enter checks it. Fit, Mobile (up to 375 px), Tablet (up to 768 px), and Desktop (up to 1,280 px) change the preview width, not the code. Reset preview leaves editor text in place. Clear workspace asks for confirmation before removing editors, feedback, preview, and import text.
Individual Copy buttons copy one editor. If clipboard access is unavailable, Foxger selects that editor text for manual copying. Code remains temporary and is not restored after a reload.
Optional advanced input
Import a complete HTML document after learning the editors
The normal starting point is three separate editors. If you already have a complete HTML document, open Paste a complete HTML document, paste it, and select Import into editors.
Foxger uses the browser’s disconnected template parser when available and extracts page/body markup.
Inline <style> blocks are combined in source order and prepared for the CSS editor.
Ordinary inline classic scripts are combined in source order. Module scripts are imported in module mode when no classic script is present.
If classic and module scripts are mixed, Foxger keeps the classic scripts, skips the modules, and warns instead of merging them silently.
External scripts and stylesheets, JSON/JSON-LD, import maps, and unsupported script types are skipped and reported.
Restricted HTML and CSS resources are removed. Import never executes JavaScript automatically.
Import is local, conservative, and not a lossless round trip. Review every warning and all three editors before deciding whether to run the result. The complete-document limit is 300,000 characters; an oversized paste remains in the import box without replacing the editors.
Keep a local copy
Download the combined page
Download HTML creates foxger-web-playground.html with the MIME typetext/html;charset=utf-8. Foxger prepares the current HTML and CSS with the same resource-removal rules, then places HTML, CSS, and JavaScript into one fixed encoded bootstrap. Copy combined HTML creates the same document text on the clipboard.
When you open the file, its JavaScript runs as part of a normal local page—not inside Foxger’s opaque-origin iframe sandbox. The generated file still includes its restrictive CSP plus link and form protections, but it does not gain missing packages or remote dependencies. Review the code before opening, sharing, or adapting it.
Beginner boundary, advanced details
What the restricted preview can—and cannot—do
The practical safety explanation
The preview runs in a separate restricted iframe with an opaque origin.
It cannot read Foxger’s parent DOM, cookies, stored theme preference, or parent JavaScript objects through same-origin access.
Ordinary external requests and remote resources are blocked or removed during normal preview use.
Links cannot navigate the Foxger parent page, and forms cannot submit normally.
Run only code you understand or trust. An endless synchronous loop can still freeze the tab.
What external-resource blocking means
Version one intentionally does not support ordinary remote scripts, stylesheets, fonts, images, frames, API/fetch requests, WebSockets, workers, or npm packages. If an online tutorial tells you to paste a CDN link, that part may not work here. This is a deliberate preview boundary, not a broken CDN.
Data and Blob image or media resources, data fonts, and local fragment references may work where the CSP allows them, but the Playground has no file upload. Do not add workarounds that weaken the preview boundary.
Advanced security architecture
The iframe uses sandbox="allow-scripts" withoutallow-same-origin, plus no-referrer. Its deny-by-default CSP permits the inline bootstrap, prepared styles, and listed data/Blob media while denying network, frame, worker, object, form-action, and base-URL sources.
HTML preparation removes executable, embedded, navigational, form, HTTP-equivalent, and ordinary resource-bearing markup. CSS preparation removes external@import rules and external resource declarations while preserving line breaks.
User code and preview identity values travel as UTF-8 Base64 payloads. Each run gets a fresh token and run ID. The parent accepts postMessage data only from the current frame when its channel, identity, bounded shape, and lengths match.
Console transport allows at most 50 arguments and 5,000 characters per value, with bounded depth, keys, and array items. The visible Console keeps 200 entries and reports dropped older entries. No live object crosses into Foxger.
This is not a virtual machine or absolute isolation. Foxger cannot reliably interrupt every endless loop, and hostile code may attempt to replace its own frame and start a navigation request. It is not a malware-analysis environment.
Size limits
Each editor warns above 50,000 characters and stops language analysis and preview execution above 100,000. Run, combined copy, and download also stop when the three editors exceed 300,000 characters in total. Foxger does not silently truncate the editor code.
No. The editors, checkers, preview builder, and download builder run in your browser. Foxger does not send your HTML, CSS, or JavaScript to a server.
Does Foxger save my code?
No. Code stays in memory for the current page and is not written to local storage, session storage, cookies, IndexedDB, or the Foxger page URL. Reloading the page clears it.
Can this tool find every HTML, CSS, or JavaScript error?
No. Foxger checks common HTML problems, CSS syntax and many declaration values, and JavaScript syntax. It cannot prove complete standards compliance, accessibility, browser compatibility, or correct program logic.
Why can the preview work when Foxger reports a problem?
Browsers often repair incomplete HTML or ignore a broken CSS declaration. A visible preview therefore does not prove that the source is well formed or accessible.
What is the difference between a syntax error and a runtime error?
A syntax error means the code cannot be parsed as written. A runtime error happens after valid JavaScript starts running, such as when code tries to change an element that does not exist.
Why did my JavaScript not run automatically?
Foxger automatically previews only HTML and CSS. After you edit JavaScript, it waits for you to select Run all code so you can review the script before executing it.
Can I use external scripts, images, fonts, or APIs?
Not as a supported playground feature. The restricted preview removes common external resources and blocks common network APIs, frames, workers, and form submissions. Data and Blob image resources may work, but this version has no file uploads. Do not use the tool to test unknown or hostile code.
Can I import a complete HTML document?
Yes. Foxger can separate body markup, inline styles, and ordinary inline scripts into the three editors. Import is local and conservative, not a lossless round trip, and skipped external or unsupported resources are reported.
Can JavaScript freeze the preview?
Yes. A synchronous endless loop can make the browser tab unresponsive. The sandbox limits permissions and network access, but it cannot reliably interrupt every program after execution begins.
Does the tool support React, TypeScript, or npm packages?
No. Version one supports browser HTML, CSS, and standard JavaScript in classic-script or ES-module syntax mode. It does not compile frameworks, JSX, TypeScript, Sass, or external packages.
Can I publish, share, or download the page?
Foxger does not host projects or create shareable code URLs. Download HTML creates foxger-web-playground.html locally. When opened, it runs outside Foxger’s iframe sandbox, so review the combined code first.
Is the sandbox safe for unknown code?
No. The preview has an opaque origin, a restrictive Content Security Policy, and safeguards against common external requests, but browser sandboxing cannot guarantee that hostile code is harmless or prevent every possible side effect. Use it only for ordinary code that you understand or trust.
Primary references
Official and project references
These sources document the languages, editor, checkers, and browser security features used by the Playground.