Generate a color-scheme meta tag and CSS property
This color-scheme meta tag generator turns one clear support choice into two copy-ready declarations: the HTML meta element used in a document head and the matching CSS color-scheme property.
Run — free
Choose light when a page only supports a light interface, dark when it only supports a dark interface, or both when every relevant component has been designed for either appearance. The result is deterministic, normalized, and ready for a template, stylesheet, static site, component library, or build pipeline without remembering attribute names or value ordering.
Declare the schemes your interface genuinely supports
The color-scheme declaration is a promise about the page, not an automatic theme converter. Select light only when controls, backgrounds, text, borders, images, and focus states remain usable in a light presentation. Select dark only when those same parts have been deliberately prepared for a dark presentation. Choose both when the complete interface works in either scheme. The generator maps that last choice to the ordered value <code>light dark</code>, which advertises support for both while listing light first. Being accurate matters because browsers can use this information when rendering browser-controlled interface pieces such as form controls, scrollbars, and the canvas behind the document. A declaration that exaggerates support can therefore produce a page with mismatched native controls or unreadable flashes around content. Before copying the output, review states that are easy to miss: disabled inputs, autofill styling, validation messages, selected text, code blocks, embedded widgets, and icons with fixed fills. The best value is the narrowest truthful description of what the shipped page supports. This tool formats that description consistently; your design and testing establish whether the description is true.
Place the generated HTML and CSS in the right locations
Put the generated meta element inside the document's <code><head></code>, preferably early enough that the browser sees it before painting substantial interface chrome. The returned tag is complete, so it can be pasted into a static HTML document, a server-rendered layout, or the head configuration of a site generator. Put the CSS declaration in a rule that represents the scope you intend to describe. For a whole document, that will commonly be the <code>:root</code> rule; a component may instead apply the property to its own root when it establishes a contained scheme. The generator returns the bare declaration rather than wrapping it in a selector, which keeps it useful across plain CSS, preprocessors, CSS modules, and style objects that perform their own conversion. The HTML and CSS outputs use the same normalized value, avoiding a subtle disagreement between document metadata and stylesheet behavior. You may use both outputs together when your architecture benefits from an early document hint plus an explicit cascade value. You may also use only the output appropriate to your integration, but do so intentionally. After insertion, inspect the final rendered source and compiled CSS because frameworks, head managers, minifiers, or duplicate declarations can change which value actually reaches the browser.
Treat support declarations separately from theme selection
Supporting two schemes and choosing the active theme are related but different jobs. The value <code>light dark</code> says that either rendering is supported; it does not create color tokens, add a theme switcher, save a preference, or replace media queries. A robust implementation normally defines semantic variables for surfaces, text, borders, and accents, then changes those variables through the strategy the product has chosen. That strategy might follow the user's operating-system preference, honor an account setting, respond to a document attribute, or combine these approaches. Generate the declaration only after deciding which visual states are genuinely complete. Then test the page with light and dark system settings, forced browser overrides where available, keyboard navigation, zoom, and high-contrast or forced-color modes. Also check content that does not inherit your palette, including images, iframes, third-party forms, syntax highlighting, and native dialogs. In automation, store the selected input alongside the generated strings so reviewers can see the intention rather than reverse-engineering it from markup. If a product later drops one theme, regenerate both declarations from the new single choice instead of editing one output manually. Keeping the meta element and CSS property derived from one source prevents drift across templates, packages, and deployments.
What you can do with it
Prepare a new page head
Create a correct meta element for a static page or server-rendered layout without recalling the exact name and content syntax.
Keep CSS and metadata aligned
Generate both declarations from one support choice so a stylesheet cannot accidentally advertise a different scheme from the document head.
Automate theme scaffolding
Use the deterministic output in a project generator, documentation pipeline, component starter, or configuration-driven build.
FAQ
What does both generate?
It generates the value light dark, producing a meta tag with that content and a matching color-scheme CSS declaration.
Does this tool create a dark theme?
No. It declares supported schemes. You still need suitable colors, assets, states, and a theme-selection strategy.
Should I use the meta tag, the CSS property, or both?
Use the output your architecture requires. Using both can provide an early document-level hint and an explicit value in the CSS cascade.
Can I provide no scheme and rely on a default?
No. A scheme is required because silently choosing one could falsely describe what your page supports.
How much does the API call cost?
Each API request costs $0.002. The browser experience can run the same deterministic logic locally.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/web/color-scheme-meta-generate \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"scheme":"both"}'const res = await fetch("https://api.kit.forhosting.com/web/color-scheme-meta-generate", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"scheme": "both"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/color-scheme-meta-generate",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"scheme": "both"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/color-scheme-meta-generate", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"scheme":"both"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"scheme":"both"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/color-scheme-meta-generate", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"scheme": "both"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.color_scheme_meta_generate",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
timeout_sec | 30 |
max_crawl_pages | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |