Curtain size calculator
A 60 by 80 window at fullness 2, with side hems of 3 and header and bottom hems of 8, needs a piece of fabric 126 wide and 96 long. Enter your window, gather and hems to get the cut size and area. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Window width
- 60
- Window height
- 80
- Fullness
- 2
- Side hem
- 3
- Top hem
- 8
- Bottom hem
- 8
- Finished width
- 120
- Hem width total
- 6
- Hem length total
- 16
- Curtain width
- 126
This curtain size calculator turns a window width, a window height, a fullness factor, and the three hem allowances into the fabric rectangle you should cut. Home sewers use it before buying a bolt, rental desks use it to quote a pair of drapes, and interior students use it when a worksheet asks for finished cloth rather than a tape-measure guess. The engine multiplies window width by fullness and adds both side hems to produce curtain width; it adds the header and the bottom hem to window height to produce curtain length; then it multiplies those two sides to report fabric area.
Where curtain-size planning fits in sewing, teaching, and software
People meet curtain-size math when a rental quotes a sixty-inch opening and nobody can say whether that is two yards of cloth or six, when a home sewer must order a bolt before the weekend, or when a teacher asks students to convert a measured window, a fullness factor, and three hem folds into a cut rectangle.
Shoppers can pre-check a sixty-by-eighty opening at fullness two with three-unit side hems and eight-unit header and bottom hems before they treat the fabric aisle as a sunk cost, and workrooms can compare a sparse gather against a dense pinch-pleat look without opaque spreadsheet macros. Contest and homework practice often needs a fast, offline source of cut sizes so solutions can be checked without a drapery catalog under time pressure.
Product and education tools use the split when a learner types an opening and the interface must show a clean width, length, and area beside the echoed inputs. Pair it with fabric-weight or thread-count helpers when you are assembling a small lab of free, deterministic textile-planning tools.
What you can do with it
Cut fabric before sewing a pair of curtains
Turn a measured window, a fullness factor, and hem allowances into curtain width, curtain length, and fabric area before you buy a bolt.
Homework and interior-design worksheets
Generate a reproducible cut rectangle from window dimensions, fullness, and hems, including the doubled side-hem step.
FAQ
What does the curtain size calculator cost?
It is free in your browser on this page.
How is required fabric size defined?
Each numeric field is rounded to ten decimal places.
What fullness factor should I use?
A light pencil gather is often about 1.5. A standard gathered heading is about 2. Pinch pleats or a luxury fold are often 2.5 to 3. Enter the rate you actually sew.
Does this convert units or count fabric bolt widths?
Bolt-width division, lining layers, and waste percentages are out of scope.
Why is the side hem counted twice?
Because a curtain panel has a left and a right edge, and each one is folded. A 60-wide window at fullness 2 gives 120, and two side hems of 3 bring the cut width to 126.
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/life/curtain-size \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"window_width":60,"window_height":80,"fullness":2,"side_hem":3,"top_hem":8,"bottom_hem":8}'const res = await fetch("https://api.kit.forhosting.com/life/curtain-size", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"window_width": 60,
"window_height": 80,
"fullness": 2,
"side_hem": 3,
"top_hem": 8,
"bottom_hem": 8
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/life/curtain-size",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"window_width": 60,
"window_height": 80,
"fullness": 2,
"side_hem": 3,
"top_hem": 8,
"bottom_hem": 8
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/life/curtain-size", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"window_width":60,"window_height":80,"fullness":2,"side_hem":3,"top_hem":8,"bottom_hem":8}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"window_width":60,"window_height":80,"fullness":2,"side_hem":3,"top_hem":8,"bottom_hem":8}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/life/curtain-size", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"window_width": 60,
"window_height": 80,
"fullness": 2,
"side_hem": 3,
"top_hem": 8,
"bottom_hem": 8
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "life.curtain_size",
"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_abs_value | 1000000000000000 |
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
Every dimension must be a positive finite number — zero or a negative tape reading is rejected as invalid_input so a missing measurement is not treated as a valid cut. Run it free in the browser for everyday sewing, or call the API at $0.002 per successful request when a quote sheet, classroom demo, or inventory script needs the same figure.
What a curtain-size result means and what the response contains
A curtain-size result is the cut rectangle of cloth that will cover a measured opening once you have chosen how generously the hanging panel should gather and how much extra you will fold into hems. Zero inches is not treated as a valid empty window here, because a zero tape reading is almost always a missing measurement rather than a planned opening. If you need a fabric-weight conversion, a thread-count converter, or a lining-yardage planner, use a dedicated helper; this page is the curtain-size sewing landing. It is not the rod-to-sill tape reading by itself, and it is not a shopping count of fabric bolts: it is the finished width after fullness plus both side hems, the finished length after header and bottom hem, and the product of those two sides as fabric_area. This calculator answers that with a closed form. finished_width equals window_width times fullness, the amount of cloth that will gather or pleat across the opening. hem_width_total is two times side_hem, because a left fold and a right fold are both cut from the same piece. curtain_width is those two quantities added together. hem_length_total is top_hem plus bottom_hem. curtain_length is window_height plus that pair of vertical allowances. fabric_area is curtain_width times curtain_length, so a quote sheet or a classroom check can see the rectangular area without multiplying by hand. The response echoes the six normalized inputs, returns those derived fields, and includes a method tag fullness_and_hems plus a formula string so a spreadsheet or a test can repeat the same steps without guessing. There is no hidden waste factor, no lining or interlining layer, no pair-versus-single-panel switch, and no bolt-width divider: the engine either multiplies and adds six finite positive numbers or it rejects the input with invalid_input. Rejected cases include a missing window_width, window_height, fullness, side_hem, top_hem, or bottom_hem field, a non-finite value, a magnitude above the documented ceiling, and — this is the product contract — any dimension that is not a positive number.
How window, fullness, and hem fields are read so results stay reproducible
Optional leading plus signs and scientific notation on numeric strings are allowed when they parse as finite decimals; embedded spaces, hex prefixes, and non-numeric tokens are rejected with a message that names the field so a bad cell does not become a wrong cut list. Typical fullness sits around one and a half for a light pencil gather, two for a standard gathered heading, and two and a half to three for pinch pleats or a luxury fold; typical side hems sit around two to four units each side, and typical header and bottom hems sit around six to eight units, but the engine does not lock those conventions — it only uses the numbers you give. All six fields share one length unit for the whole request: inches, centimetres, or metres, as long as you do not mix them. Computation uses ordinary floating-point multiplication and addition, then rounds each numeric field to ten decimal places so goldens stay stable across runtimes. The preferred field for the opening is window_width, but aliases width, opening_width, and window_w are accepted so a form, a query string, or a spreadsheet column can reuse the same contract without renaming cells. Height prefers window_height, with aliases height, drop, opening_height, and window_h. Fullness prefers fullness, with aliases fullness_factor, gather, and gather_factor. Side hem prefers side_hem, with aliases side_allowance, hem_side, and side_hem_allowance. The header prefers top_hem, with aliases header, header_allowance, top_allowance, and heading. The bottom fold prefers bottom_hem, with aliases hem, hem_allowance, bottom_allowance, and bottom_hem_allowance. Every one of those six values must be strictly greater than zero: that is the product contract, and a missing, zero, or negative tape reading is invalid_input. Pair the free browser run on this page with the priced API when you need that identical mathematical result inside an automated quote or inventory pipeline without re-implementing the cut rule yourself.
Where curtain-size planning fits in sewing, teaching, and software
Developers call the same contract from scripts to seed deterministic test vectors for sewing calculators, to normalize user-entered windows before a quote demo, or to satisfy a product statement that demands curtain_width, curtain_length, and fabric_area fields rather than a hand-waved estimate. On this page the work runs entirely in your browser; through the API each successful lookup costs $0.002, failed validation is not charged, and nothing is stored after the response returns. That split — free interactive exploration and a priced, identical API — matches the rest of the tier-A catalog and lets you move from a classroom demo to an automated pipeline without changing the mathematical result.
Integration use cases
Quote tools and test fixtures
Normalize window and hem inputs into stable curtain_width, curtain_length, and fabric_area fields for product interfaces and continuous-integration assertions.
Technical questions
What happens if a dimension is zero or negative?
The input is rejected with invalid_input. window_width, window_height, fullness, side_hem, top_hem, and bottom_hem must each be a positive number.