Straight Stair Calculator

Overall dimensions
Steps
Stringers
Timber stock

Headroom is not a constraint here — this stair never passes under the ceiling above.

Diagram
Side elevation
Front elevation
Plan view
Side elevation detail (first steps)
Riser height171mm
Tread depth305mm
Dimensions
STotal run4.48 m
MPitch angle32.9°
KRiser height171 mm
LGoing280 mm
OTread depth305 mm
NStringer length5,337 mm
Number of risers17
Headroom
Opening would need to start at (from base)815 mm
Opening would need to be at least3.67 m
Materials
Stringer timber required (both sides)10.67 m
Total tread area4.39 m²
Tread timber volume140.54 L
Stringer timber volume116.01 L
Tread timber, linear length14.4 m
Tread boards to buy3
Riser timber, linear length15.3 m
Riser boards to buy3
Stringer timber, linear length10.67 m
Stringer boards to buy2
Parts list
TreadCount: 16
Length
900 mm
Width
305 mm
Thickness
32 mm
RiserCount: 17
Length
900 mm
Width
139 mm
Thickness
19 mm
StringerCount: 2
Length
5,337 mm
Width
286 mm
Thickness
38 mm

About this calculator

This calculator helps design a straight flight of stairs from an existing floor opening: enter the opening's dimensions, the total rise (floor to floor), and your preferred riser height, and it works out the riser count, each step's dimensions, checks headroom along the whole climbed path, and produces a drawing plus a timber cutting list. The result is the drawing itself, not a single number: this is a design (kind: 'design') calculator, not a quantity one.

Formula

The opening is the primary given, not a result — it is measured against an existing (or planned) hole in the floor, not a stair someone has already designed. Everything else is derived from it and the total rise:

riser count = round(total rise / preferred riser height)   (clamped to 2-20)
riser height = total rise / riser count   (exactly, with no lost remainder)

tread count = riser count - 1, if the top tread sits flush with the floor
            = riser count,     if every riser gets its own tread

The riser count is no longer a direct input field — that used to require the user to already know the answer. Now only a preferred riser height (targetRiserHeight) is entered, and the real riser count and exact height are derived from it and the total rise.

Going (tread depth minus nosing) — two paths:

if openingExactFit = false (DEFAULT since 2026-08-23):
  going = your own `going` input
  total run = going × tread count   (independent of the opening length)

if openingExactFit = true (opt-in):
  total run = opening length - nosing overhang
  going = total run / tread count

Why the default changed: in real practice a floor opening is normally cut LARGER than the flight and the flight fixed against one edge of it, leaving the rest of the hole open past the flight's own base (usually over the landing, or the room below) — an opening that exactly matches the flight's own length is the rarer case, not the general one. So openingExactFit = false (the new default) treats going as a real, independent design input — the opening length plays no part in sizing the flight at all. openingExactFit = true remains available for the case where the opening genuinely was cut to the flight's own size — then the opening genuinely determines the going and the whole run, as described below.

Why the nosing overhang is subtracted (openingExactFit = true path only): every tread's own nosing projects forward past its own riser line by exactly noseOverhang — including the FIRST tread, whose nosing projects past the flight's own starting point itself. If the total run were set to exactly the opening's own length (no subtraction), the opening's near edge would always coincide with the flight's own starting point, and the first tread's nosing would always sit just outside the opening's own boundary — no matter how the opening was sized or positioned. Subtracting the nosing overhang from the total run puts the opening's near edge exactly nosing overhang before the flight's own starting point (see below) — exactly enough for the first tread's own nosing to fall inside it.

pitch angle = atan2(total rise, total run)
stringer length = √(total rise² + total run²)

The flight's position under the opening: the flight's top structurally always lands at the opening's far edge (that is where the upper floor's surface begins). The opening's near edge (reference A) is a derived value, not an input: total run − opening length. Under openingExactFit = false (the default), this is typically well negative — a real opening is normally cut larger than the flight, so going (a real input, not derived from the opening) usually produces a run shorter than the opening, meaning the flight's own base already sits inside the opening's own footprint. Under openingExactFit = true (opt-in), this value is always exactly minus the nosing overhang (e.g. -25 mm with the default 25 mm overhang) — not zero — because the run is then, by construction, the opening length minus the nosing overhang (see above). There is no longer a separate "opening start" field — its old definition ("from the flight's own base") no longer makes sense once the flight's own base is itself a derived, moving position.

The flight's position across the opening's width is set by stairPositionInOpening (left/centered/right) — the one remaining free position choice. The reference point is the climber themselves, standing at the base of the flight facing it, before taking the first step: 'right' always means the climber's own right hand, not the drawing's own +X axis (model +X is the climber's LEFT hand). This convention is shared by every stair calculator on this platform (see CLAUDE.md).

Headroom is checked along the whole climbed path under the ceiling — every tread that falls before the opening's own near edge, measured as the vertical distance from its nosing to the ceiling (total rise minus floor structure thickness), assuming the ceiling runs uncut across that whole span. If the smallest such clearance is below the required headroom, an error is returned along with how far the opening would need to extend. The calculator also reports the minimum opening length (and its own start point) that would be needed for headroom alone — independent of the opening you actually entered.

The step-comfort check (2×riser+going) and the pitch-comfort check (30-45°) are unchanged from before — see below, Assumptions and limits.

Worked example

Defaults: opening length 4700 mm, opening width 1100 mm, stair centered in the opening, total rise 2900 mm, stair width 900 mm, preferred riser height 175 mm, going 280 mm (a real input, openingExactFit = false), top tread flush with the floor, tread thickness 32 mm, nosing overhang 25 mm, riser board thickness 19 mm, stringer thickness 38 mm, stringer depth 286 mm, floor structure thickness 300 mm, required headroom 2000 mm, standard board length 6000 mm.

riser count = round(2900 / 175) = round(16.571) = 17
riser height = 2900 / 17 ≈ 170.59 mm
tread count = 17 - 1 = 16 (top tread flush with the floor)

going = 280 mm   (a real input, opening length plays no part)
total run = 280 × 16 = 4480 mm
tread depth (incl. nosing) = 280 + 25 = 305 mm
opening's near edge = 4480 - 4700 = -220 mm

pitch angle = atan2(2900, 4480) ≈ 0.5745 rad ≈ 32.92°
stringer length = √(2900² + 4480²) ≈ 5336.70 mm

2×riser+going = 2×170.59 + 280 ≈ 621 mm  (inside the 600-660 mm band -> no warning)

ceiling height under the floor = 2900 - 300 = 2600 mm

The opening's near edge (-220 mm) sits just before the flight's own starting point — the opening (4700 mm) was deliberately cut larger than the flight (4480 mm), as is normal in real practice (see Formula), so ALL 16 treads fall inside the opening. The calculator returns an informational note that no tread sits under a still-solid part of the floor. The separate, headroom-only "what opening size would this need" answer in this case returns a start point of ≈815 mm and a length of ≈3665 mm — an isolated figure, independent of the opening actually in use, showing that a considerably more modest opening (from ≈815 mm up to the flight's own top) would also satisfy headroom alone.

For these inputs the calculator returns exactly this: riser height ≈170.59 mm, going 280 mm, tread depth 305 mm, total run 4480 mm, stringer length ≈5336.70 mm, 17 risers, 16 treads. Diagnostics: a single informational note that no tread sits under a still-solid part of the floor — no warnings (2×riser+going = 621 mm falls inside the 600-660 mm band).

Timber list for these inputs: 16 tread boards (900×305×32 mm each — needing 3 boards of 6000 mm, total length 14,400 mm), 17 riser boards (900×≈138.59×19 mm each, needing 3 boards of 6000 mm — total length 15,300 mm), 2 stringers (each ≈5336.70×286×38 mm, total length ≈10,673.41 mm, needing 2 boards of 6000 mm).

FAQ

Why isn't the riser count among the inputs any more? Because that used to require the user to already know the answer. Now only a preferred riser height (targetRiserHeight) is entered — the real riser count and exact height are computed from it and the total rise.

Does the opening only get checked, or does it genuinely set the going? That depends on openingExactFit. By default (false), the going comes from your own going field, and the run is computed from it — the opening length plays no part in sizing it, since a real opening is normally cut larger than the flight it serves. Switching openingExactFit on makes the opening genuinely set both the going and the whole run instead — the total run then always ends up equal to the opening length minus the nosing overhang (see Formula — not exactly the opening length, so the first tread's own nosing falls inside the opening) — useful when the opening genuinely was cut to the flight's own size. The comfort check still runs and warns if the result falls outside the 2×riser+going band either way.

Why isn't there a separate "opening start" field any more? Because it used to be defined relative to the flight's own base, and the flight's base is now a derived, moving position, not a fixed second reference point. The opening's near-edge position is now shown as a result (on the drawing, labelled A), not entered.

What do 'left'/'right' mean for the flight's position in the opening? The climber's own right/left hand, standing at the base of the flight facing it — not a drawing axis. The same convention is used across every stair calculator on this platform.

Is headroom checked at just one point? No — every tread that falls before the opening's own near edge is checked, and the smallest of those clearances is reported. The calculator also reports the minimum opening length that would be needed for headroom alone — an answer to "how much would be enough", independent of the opening you actually entered.

Why does the calculator mention two different standards for the 2×riser+going check? Because DIN 18065 and Lithuanian STR 2.02.01:2004 both define the same formula, but with different targets (630 mm and 650 mm respectively) — a real disagreement between the two standards, which the calculator reports honestly rather than silently picking one as "correct".

Does the timber list account for cutting waste? No. Each member type's total required length is simply divided by the standard board length and rounded up — that is a quantity estimate, not an optimized cutting plan.

Assumptions and limits

meta.standards cites DIN 18065 and STR 2.02.01:2004 — both used for the same 2×riser+going comfort formula, but with different targets (630 mm and 650 mm) — this disagreement is reported, not resolved, by the calculator. The 30-45° pitch comfort band is a general rule matching neither of these two standards exactly, and no standard is cited for that check.

The required headroom is a user input with no cited minimum — it is set by national or local requirements that differ from each other, so the calculator does not state which one applies.

The preferred riser height (targetRiserHeight) is bounded to 150-200 mm — the upper bound matches STR 2.02.09:2005 §47.4's interior riser-height ceiling (≤200 mm); the lower bound is this calculator's own judgment call (a shallower target only ever lengthens the run), not a cited source. The exact-fit-to-opening path's own internal clamp (220-400 mm) is only a sanity range for that path itself — the going field's own bounds (150-500 mm, applied in the default openingExactFit = false path) are deliberately wider, since a real design choice routinely needs to go outside the comfortable range when floor space demands it; a separate diagnostic, not these bounds, reports whether the result is comfortable.

This calculator is one of two on this platform that return parts[] — real physical pieces (treads, risers, stringers) with actual cutting dimensions, not just a total material quantity. The timber board count is a simple quantity division by the standard board length, not an optimized cutting plan.

The stringer's remaining depth below the notch (shown on the detail drawing) has no cited minimum — the required remaining depth depends on span tables that vary by jurisdiction.

kalkivo