U-Shaped Stair with Landing Calculator

Overall dimensions
Landing
Steps
Stringers
Timber stock

This stair clears every point along it — minimum headroom is 2150 mm, at the landing, above the 2000 mm required.

Diagram
Riser height175mm
Tread depth305mm
Minimum headroom clearance2.15m
Dimensions
NRiser height175 mm
OGoing280 mm
PPitch angle32.0°
UTread depth305 mm
QLower flight run1.4 m
RUpper flight run3.64 m
WLanding height (above base floor)1.05 m
XUpper flight rise2.45 m
YLanding width (both flights + well)1.9 m
SLower flight stringer length1,750 mm
TUpper flight stringer length4,388 mm
Risers, lower flight6
Risers, upper flight14
Headroom
Minimum headroom clearance2.15 m
Opening would need to start at (from landing)-25 mm
Opening would need to be at least3.67 m
Materials
Stringer timber required (all 4)12.28 m
Total tread area4.94 m²
Tread timber volume158.11 L
Stringer timber volume133.42 L
Tread timber, linear length16.2 m
Tread boards to buy4
Riser timber, linear length16.2 m
Riser boards to buy4
Stringer timber, linear length12.28 m
Stringer boards to buy3
Parts list
TreadCount: 18
Length
900 mm
Width
305 mm
Thickness
32 mm
RiserCount: 18
Length
900 mm
Width
143 mm
Thickness
19 mm
Stringer, lower flightCount: 2
Length
1,750 mm
Width
286 mm
Thickness
38 mm
Stringer, upper flightCount: 2
Length
4,388 mm
Width
286 mm
Thickness
38 mm

About this calculator

This calculator helps design a U-shaped (180° turn) stair with a landing — two parallel flights running in opposite directions, joined by a landing and separated by a gap (well width) between them — from an existing floor opening. The formulas are the same as the L-shaped stair calculator (both share the same underlying flight-geometry logic and the same "opening-first" model), but here there is an extra well-width parameter, and the landing's width is always computed from the flight width and well, never entered directly. Like the other stair calculators, this is a design (kind: 'design') calculator — the result is the drawing itself.

Formula

The opening is the primary given, not a result — the same principle as the L-shaped and straight-stair calculators:

total riser count = round(total rise / preferred riser height)
riser height = total rise / riser count   (one division for the whole stair, exactly)

lower flight riser count = round(landing height target / riser height)
upper flight riser count = total riser count - lower flight riser count

Going is applied UNIFORMLY to both flights, and its source depends on openingExactFit:

if openingExactFit = false (DEFAULT since 2026-08-23):
  going = your own `going` input
  upper flight run = going × upper flight tread count

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

lower flight run = going × lower flight tread count   (the same going, from above)

The lower flight has no opening of its own, so its own run simply inherits the same going.

Why the default changed: in real practice a floor opening is normally cut LARGER than the upper flight and the flight fixed against one edge of it — an opening that exactly matches the upper 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 either flight. openingExactFit = true remains available for the case where the opening genuinely was cut to the upper flight's own size — then the opening genuinely sets the going and the whole upper-flight run, as described below; the comfort formula remains only a separate diagnostic that checks the result, not its source, either way.

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 of the upper flight, whose nosing projects past the flight's own starting point itself. If the upper flight's 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. That was a modelling bug, not physics (see the L-shaped stair calculator's own Formula — identical problem and fix, since both calculators share the same underlying flight-geometry logic).

opening's near edge (from the landing) = upper flight run - opening length   (may be negative)

The upper flight's top (the point furthest from the landing, where it reaches the true top floor) must always land at the opening's far edge. 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), the upper flight's run is, by construction, always equal to the opening length minus the nosing overhang, so the opening's near edge is always exactly minus the nosing overhang (e.g. -25 mm with the default 25 mm overhang) — not zero — exactly enough for the first tread's own nosing to fall inside the opening.

landing depth (direction of travel) = flight width (if equal) or your own entered value
landing width (perpendicular to travel) = flight width × 2 + well width   (always derived, never entered)
landing height (actual) = sum of the lower flight's own risers

tread depth (incl. nosing) = going + nosing overhang
pitch angle = atan2(riser height, going)
each flight's stringer length = √(that flight's rise² + that flight's run²)

Unlike the L-shaped stair, the two flights here are parallel and run in opposite directions, not perpendicular to each other — separated by the well width. The landing's width is never entered directly — it always equals flight width × 2 + well width, so it can never structurally be narrower than a single flight.

Headroom is checked along the whole climbed path — every tread of the lower flight, the landing itself, and every tread of the upper flight, not just the upper flight. Each point has its own plan footprint and its own height; it is checked against one flat ceiling line (measured from the base floor) and against the opening rectangle — a point is exempt from the check only if its footprint falls entirely inside the opening, not merely overlapping it.

The landing depth check (IRC R311.7.6, the same wording as the L-shaped stair) applies to the landing's depth, not its width — since the width (always 2×flight width+well) can never structurally be narrower than a single flight, this check would not mean anything for it.

The step-comfort (2×riser+going) and pitch-comfort (30-45°) checks use the same criteria and the same two standards as the other two stair calculators.

Worked example

Defaults: opening length 3665 mm, opening width 1100 mm, total rise 3500 mm, stair width 900 mm, well width 100 mm, floor structure thickness 300 mm, required headroom 2000 mm, top tread flush with the floor, landing depth equal to stair width, landing height target 1050 mm, preferred riser height 175 mm, going 280 mm (a real input, openingExactFit = false), tread thickness 32 mm, nosing overhang 25 mm.

total riser count = round(3500 / 175) = 20   (divides evenly)
riser height = 3500 / 20 = 175 mm   (exactly)

lower flight riser count = round(1050 / 175) = 6
upper flight riser count = 20 - 6 = 14

upper flight tread count = 14 - 1 = 13 (top tread flush with the floor)
going = 280 mm   (a real input, opening length plays no part)
upper flight run = 280 × 13 = 3640 mm
opening's near edge = 3640 - 3665 = -25 mm

lower flight tread count = 6 - 1 = 5 (the landing itself is the last "tread")
lower flight run = 5 × 280 = 1400 mm

landing depth = 900 mm; landing width = 900 × 2 + 100 = 1900 mm
landing height = 6 × 175 = 1050 mm   (exactly matches the target)

tread depth = 280 + 25 = 305 mm
pitch angle = atan2(175, 280) ≈ 0.5586 rad ≈ 32.01°

lower stringer length = √(1050² + 1400²) = 1750 mm   (exactly)
upper stringer length = √(2450² + 3640²) ≈ 4387.72 mm

For these inputs the calculator returns exactly this: riser height 175 mm, going 280 mm, tread depth 305 mm, landing width 1900 mm, landing height 1050 mm, lower stringer length 1750 mm, upper stringer length ≈4387.72 mm, 6 risers in the lower flight and 14 in the upper.

Headroom: for these defaults the calculator passes cleanly with no warnings or errors at all — the smallest clearance (2150 mm, a 150 mm margin over the required 2000 mm) is found at the LANDING ITSELF, not the upper flight: since the opening's near edge is now exactly -25 mm (see Formula), the opening fully covers the first upper tread's own nosing, so the whole upper flight is exempt from the check. 2×riser+going = 2×175+280 = 630 mm — exactly DIN 18065's own target, dead centre of the comfort band.

The separate, upper-flight-only "what opening size would this need" answer returns a start of -25 mm and a length of 3665 mm — exactly matching the actual opening length, since these defaults were chosen so the opening exactly satisfies this isolated, upper-flight-only requirement. It evaluates only the upper flight's own need, in isolation from the whole-path check above, and doesn't have to match it.

Timber list: 18 treads (5 in the lower flight + 13 in the upper) × 900 mm wide × 305 mm deep tread boards — 4 boards of 4800 mm. 18 riser boards (out of 20 risers total — 2 risers, which top the landing/floor rather than a tread, are skipped because their board height is smaller than the floor structure thickness): also 4 boards. 4 stringers (2 lower at 1750 mm, 2 upper at ≈4387.72 mm, ≈12,275.44 mm in total): 3 boards.

FAQ

Why isn't the going derived from the 2×riser+going formula any more? Because that was an earlier, not-yet-fully-applied cut of the "opening-first" model — the opening was only checked back then, not genuinely used to size the going. By default today (openingExactFit = false), going is a real input instead; the comfort formula remains only a separate diagnostic that checks the result. Switching openingExactFit on derives the going (and the whole upper-flight run) directly from the opening length instead.

Why is the landing checked together with the flights, not separately? Because the headroom check now covers the whole climbed path — every tread of the lower flight, the landing itself, and every tread of the upper flight — compared against one shared ceiling line, not just the upper flight. The opening only exempts points whose whole floor-plan footprint falls inside it.

Why can the opening's near edge be negative? Because the upper flight's top must always land at the opening's far edge — a structural requirement. With the default (openingExactFit = false) values this edge is typically well negative, since a real opening is normally cut larger than the flight and going (a real input) usually produces a run shorter than the opening — see Assumptions and limits for why that reach does NOT usefully extend to relieving the landing here, unlike the L-shaped stair calculator. With openingExactFit = true, this edge is always exactly minus the nosing overhang (e.g. -25 mm with the default 25 mm overhang) — not zero — since the upper flight's run is then, by construction, the opening length minus the nosing overhang (see Formula): the first tread's own nosing needs exactly that much room in the opening before the flight's own starting point.

What is the well width (wellWidth) for? It is the gap between the two parallel flights, wide enough for a handrail on each side of an open well. This value has no cited standard — none of the three cited standards (DIN 18065, STR 2.02.01:2004, IRC R311.7.6) states a minimum well width directly.

Why is there no landing width check, only a depth check? Because the landing's width (perpendicular to the direction of travel) is always computed as 2×flight width+well width — it can never structurally be narrower than a single flight, so the IRC R311.7.6 check applies only to the landing's depth, which can end up smaller if a manual value is chosen.

Does turnDirection change any computed number here? No — it is purely a drawing parameter, deciding which side of the well the lower flight sits on. Both turnDirection and stairPositionInOpening are expressed from the climber's own left/right hand, standing at the base of the flight before the first step — not a drawing axis.

Assumptions and limits

meta.standards cites DIN 18065, STR 2.02.01:2004 (for the 2×riser+going comfort check, with the same 630/650 mm disagreement), and IRC R311.7.6 (for the landing depth check). The 30-45° pitch comfort band remains an uncited general rule. The well width's default and bounds are this calculator's own choice — none of the three cited standards directly states a minimum well width.

The required headroom is a user input with no cited minimum, applied along the whole climbed path — the lower flight, the landing, and the upper flight. requiredOpeningStart/requiredOpeningLength answer only "what opening size would suffice for the upper flight" — they do NOT reflect the whole-path check's own result, and may show that the opening you have is sufficient even when the overall check returns an error for the landing or lower flight. requiredOpeningStart can also be NEGATIVE — that is a real answer, not an invalid one: it means the opening would need to start somewhat before the flight's own starting point (to give the first tread's own nosing the headroom it needs), not that the requirement is already met right from the flight's own base.

The defaults (opening length, total rise, landing height target) were chosen so the default stair clears its own headroom check with real margin (see Worked example), not merely on a technicality — an earlier version of this calculator shipped with defaults that opened on an error. This doesn't weaken the check itself: any combination where the landing sits high enough relative to the total rise can still fail it — that remains a real, not an artificial, constraint.

Unlike the L-shaped stair calculator, raising the landing height target does NOT pay off here — verified directly, not assumed: this calculator's landing spans the WHOLE stairwell width (both flights plus the well — stair width×2 + well width = 1900 mm at these defaults), not one flight's own width (900 mm), and that landing width sits on the SAME axis (stairPositionInOpening, X here) the opening's own width also occupies — unlike the L-shaped stair, where the lower flight (and the landing's own extent) is on a genuinely PERPENDICULAR axis the opening can never reach regardless of width. For this calculator, an opening widened enough to span the landing's full 1900 mm ends up ALSO spanning the lower flight's own band, since the two sit side by side on that same axis, separated only by the well — there is no realistic intermediate opening that covers the landing but not the lower flight. Confirmed by direct test: openingWidth widened to 1900 mm or more with stairPositionInOpening = 'right' DOES clear every error — but only because it exempts the lower flight too, i.e. removes the ceiling from the ENTIRE stair, not a "cut a bit larger than the flight" opening any more. That is not the general case this default change is modelling, so it is not adopted as the default.

landingHeight (1050 mm) and openingLength (3665 mm) are therefore UNCHANGED from the previous version — and need no change: at these exact numbers, going under the new default (a real 280 mm input) comes out identical to what the OLD exact-fit derivation already produced here (split(3665-25,13) = 280 mm exactly), so the upper flight's run and the opening's near edge land on the same values either way, and the result is byte-identical to before (riser height 175 mm, going 280 mm, 2×riser+going = 630 mm, zero warnings or errors, a single informational note, a 150 mm headroom margin) — see compute.test.ts. This calculator's own landing-height ceiling stays at 30% of the rise, genuinely different from the L-shaped stair calculator's 35% — a real geometric difference between the 90-degree and 180-degree cases, not an oversight.

One floor-structure-thickness input serves both the upper floor structure and the landing's own construction thickness — the same assumption as the L-shaped stair calculator.

This calculator uses the same shared flight-geometry logic as the L-shaped stair calculator (buildFlightGeometry, parallelFlightBandLayout, planRectFullyCoveredBy, and related helpers from packages/geometry), so both calculators' riser/tread formulas, timber requirement, and parts[] structure are identical — only the landing geometry and the flights' plan orientation differ (parallel, opposite directions here; perpendicular in the L-shape). The timber board count is a simple quantity division by the standard board length, not an optimized cutting plan.

kalkivo