Generate a typographic type scale for heading levels
Start from 16 px body text and a 1.25 ratio and the headings climb in even steps: h6 is 20, h5 is 25, h4 is 31.25, and each level up multiplies by the same ratio. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
A typographic scale turns one body-text size and one ratio into a predictable hierarchy for headings. Enter a base font size, such as 16, and a positive ratio, such as 1.25 for a major third. The generator assigns successive powers of that ratio to heading levels and returns an ordered, machine-readable list from h1 downward. It is useful when creating CSS tokens, documenting a design system, or checking that a proposed hierarchy follows a consistent mathematical rule instead of a collection of unrelated sizes.
Choose a base and a ratio that match the reading context
Start with the size used for ordinary body copy. A base of 16 pixels is common on the web, but it is not a universal requirement: dense application interfaces may use a smaller value, while editorial layouts may begin at 18 or 20 pixels. The ratio determines how quickly headings move away from that base.
A ratio of 1.125 creates a restrained progression, 1.2 gives a clearly visible but moderate hierarchy, and 1.25 is often called a major-third scale. Larger ratios create dramatic display sizes quickly, especially when all six HTML heading levels are requested. This capability accepts any finite positive ratio.
A ratio of 1 produces equal sizes, and a ratio below 1 produces smaller values at higher exponents; those results can be intentional for analysis or reverse scales. Only zero and negative ratios are errors, exactly because multiplication by them cannot represent a positive modular progression. Keep the unit consistent in your own system.
The returned label is px for convenient web use, but the numeric relationship is unitless: starting with a rem value produces the same proportions. Choose the input values based on actual content, available width, font metrics, and target devices rather than relying on a named ratio alone.
Understand how heading levels are calculated
The base font size is step zero and is not itself included as a heading. For six requested levels, h6 receives base multiplied by ratio to the first power, h5 uses the second power, and the progression continues until h1 uses the sixth power. This mapping makes h1 the furthest step from body text when the ratio is greater than one, while preserving the familiar h1-to-h6 output order.
Every row reports the heading name, exponent, and computed size, so consumers do not have to infer how an array index maps to markup. Results are rounded to six decimal places to remove distracting floating-point noise while retaining enough precision for CSS variables and design-token pipelines. The optional levels field defaults to six and must be an integer from one through six, matching the standard HTML heading elements.
Extremely large generated sizes are rejected before they can produce unusable or non-finite output.
Apply the scale without confusing size and document structure
Treat the generated values as design candidates, not as instructions to choose heading tags for visual appearance. HTML heading levels communicate document structure to browsers, search engines, and assistive technology; an h2 should represent a subsection of an h1 even if a particular component renders it with a smaller token. A practical workflow is to generate the scale, copy the sizes into named tokens such as text-heading-large and text-heading-small, then map those tokens to semantic elements in component styles.
Test the largest value with real titles, narrow mobile widths, localization, bold weights, and fonts whose capital widths differ from your mockups. You may decide to use only part of the mathematical scale, clamp the largest sizes responsively, or reuse one size for multiple semantic levels. Those adaptations do not invalidate the underlying ratio; they make the system work under real layout constraints.
For review and regression testing, store the base, ratio, requested level count, and returned rows together. That record makes later changes explainable: reviewers can see whether a new visual hierarchy came from changing the body size, changing the ratio, or selecting fewer generated levels.
What you can do with it
Create CSS design tokens
Generate repeatable heading sizes, then place the returned values into custom properties or a token build pipeline.
Document a brand hierarchy
Record the base and ratio beside h1 through h6 values so designers can reproduce the typography consistently.
Compare candidate scales
Run several positive ratios against the same base and compare how quickly display headings grow across levels.
FAQ
Can the ratio be less than one?
Yes. Any finite positive ratio is valid. Ratios below one create values that decrease as the exponent increases.
How many levels can I generate?
From one through six, corresponding to standard HTML headings. If omitted, levels defaults to six.
Which ratio should I start with?
A ratio of 1.125 gives a restrained progression, 1.2 a clear but moderate one, and 1.25 the classic major third. Larger ratios reach dramatic display sizes quickly once all six heading levels are used.
Which heading gets which step of the scale?
Body text is step zero. The smallest heading, h6, is the base times the ratio once, h5 uses the ratio squared, and so on until h1 uses the sixth power, the furthest step from body text.
Can I work in rem instead of pixels?
Yes. The sizes are labelled px, but the relationship itself has no unit: start from a rem value and the proportions come out the same. Just keep one unit throughout your own system.
Related tools
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/doc/typography-scale-generate \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"base_font_size":16,"ratio":1.25}'const res = await fetch("https://api.kit.forhosting.com/doc/typography-scale-generate", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"base_font_size": 16,
"ratio": 1.25
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/doc/typography-scale-generate",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"base_font_size": 16,
"ratio": 1.25
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/doc/typography-scale-generate", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"base_font_size":16,"ratio":1.25}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"base_font_size":16,"ratio":1.25}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/doc/typography-scale-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
{
"base_font_size": 16,
"ratio": 1.25
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "doc.typography_scale_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
max_mb | 25 |
max_pages | 200 |
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. |
Technical notes
Understand how heading levels are calculated
If you request three levels, the response contains h1, h2, and h3; h3 uses the first power, h2 the second, and h1 the third. The algorithm performs no network request, reads no clock, and uses no random values, so identical inputs always return identical JSON. Input aliases support base and font_size for the base value, plus scale_ratio for the ratio.
Apply the scale without confusing size and document structure
The API costs $0.002 per successful request, while the same deterministic calculation can run in the browser. Invalid values, including a non-positive ratio, return invalid_input rather than a partial scale.
Technical questions
What formula does the generator use?
Each size is base_font_size multiplied by ratio raised to the row's reported exponent.
Why is a ratio of zero rejected?
Zero cannot create a positive proportional scale. The capability returns invalid_input for zero or any negative ratio.
How much does an API request cost?
A successful API request costs $0.002. Invalid input returns an error instead of a generated scale.