{
  "id": "stair",
  "version": "bef462e024b3",
  "status": "published",
  "name": "Stair Calculator",
  "question": "How many steps do my stairs need?",
  "summary": "Computes the number of risers and treads, riser height, tread depth, total run, angle, stringer length and headroom for a straight stair, and checks them against the IRC R311.7 limits.",
  "category": "construction",
  "url": "https://www.acalculator.org/construction/stair-calculator",
  "markdown": "https://www.acalculator.org/construction/stair-calculator.md",
  "kind": "function",
  "method": "risers = ⌈total rise ÷ largest riser⌉; riser = total rise ÷ risers; treads = risers − 1; total run = treads × tread; stringer = √(rise² + run²)",
  "assumptions": [
    "A straight flight: the upper floor is the top step, so there is one tread fewer than risers.",
    "Every riser is the same height and every tread the same depth.",
    "Limits from the International Residential Code, section R311.7: riser at most 7¾ in, tread at least 10 in, headroom at least 6 ft 8 in, and at most 151 in of rise between floors or landings. Check your local code, which may differ.",
    "Headroom is measured straight up from the sloped line through the tread nosings to the edge of the floor opening, which sits the floor thickness below the upper floor.",
    "The stringer length is the diagonal of the total rise and total run; cut the board longer to allow for the top and bottom cuts."
  ],
  "inputs": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "rise": {
        "title": "Total rise",
        "description": "The height from the finished lower floor to the finished upper floor.",
        "type": [
          "number",
          "string"
        ],
        "x-quantity": "length",
        "exclusiveMinimum": 0,
        "maximum": 30
      },
      "stepMode": {
        "title": "Number of steps",
        "description": "Whether to find the number of risers from a target riser height, or to set the number yourself.",
        "type": "string",
        "enum": [
          "fixedRise",
          "fixedSteps"
        ]
      },
      "riser": {
        "title": "Largest riser height",
        "description": "The tallest riser you want. The calculator uses the fewest risers that are not taller than this.",
        "type": [
          "number",
          "string"
        ],
        "x-quantity": "length",
        "minimum": 0.0508,
        "maximum": 1
      },
      "fixedSteps": {
        "title": "Number of risers",
        "description": "How many risers (steps up) the stair has.",
        "type": "integer",
        "minimum": 2,
        "maximum": 100
      },
      "runMode": {
        "title": "Run",
        "description": "Whether you know the depth of each tread or the total run the stair may take.",
        "type": "string",
        "enum": [
          "individual",
          "total"
        ]
      },
      "run": {
        "title": "Tread depth",
        "description": "The depth of each tread, nosing to nosing.",
        "type": [
          "number",
          "string"
        ],
        "x-quantity": "length",
        "exclusiveMinimum": 0,
        "maximum": 2
      },
      "totalRun": {
        "title": "Total run",
        "description": "The horizontal length the stair takes, from the first nosing to the face of the top riser.",
        "type": [
          "number",
          "string"
        ],
        "x-quantity": "length",
        "exclusiveMinimum": 0,
        "maximum": 30
      },
      "hasTread": {
        "title": "Tread boards",
        "description": "Whether separate tread boards sit on the stringers, which makes the first stringer cut shorter.",
        "type": "boolean"
      },
      "treadT": {
        "title": "Tread thickness",
        "description": "The thickness of the tread boards.",
        "type": [
          "number",
          "string"
        ],
        "x-quantity": "length",
        "exclusiveMinimum": 0,
        "maximum": 0.5
      },
      "hasHeadroom": {
        "title": "Check headroom",
        "description": "Whether to check the headroom under the edge of the opening in the upper floor.",
        "type": "boolean"
      },
      "opening": {
        "title": "Floor opening length",
        "description": "The length of the opening in the upper floor, measured back from the top of the stair.",
        "type": [
          "number",
          "string"
        ],
        "x-quantity": "length",
        "exclusiveMinimum": 0,
        "maximum": 30
      },
      "floorT": {
        "title": "Upper floor thickness",
        "description": "The depth of the upper floor structure at the edge of the opening, including the ceiling below it.",
        "type": [
          "number",
          "string"
        ],
        "x-quantity": "length",
        "exclusiveMinimum": 0,
        "maximum": 3
      },
      "headroom": {
        "title": "Required headroom",
        "description": "The headroom you need. The IRC asks for at least 6 ft 8 in.",
        "type": [
          "number",
          "string"
        ],
        "x-quantity": "length",
        "exclusiveMinimum": 0,
        "maximum": 5
      }
    }
  },
  "outputs": {
    "risers": {
      "label": "Risers",
      "description": "The number of risers (steps up): total rise ÷ largest riser height, rounded up, or the number you set.",
      "format": "integer"
    },
    "riserHeight": {
      "label": "Riser height",
      "description": "Total rise ÷ number of risers.",
      "format": "quantity",
      "unit": "in"
    },
    "treads": {
      "label": "Treads",
      "description": "Risers − 1: the upper floor is the top step.",
      "format": "integer"
    },
    "treadDepth": {
      "label": "Tread depth",
      "description": "The depth of each tread: as typed, or total run ÷ treads.",
      "format": "quantity",
      "unit": "in"
    },
    "totalRun": {
      "label": "Total run",
      "description": "Treads × tread depth.",
      "format": "quantity",
      "unit": "in"
    },
    "angle": {
      "label": "Angle",
      "description": "The slope of the stair: arctan(riser height ÷ tread depth).",
      "format": "quantity",
      "unit": "deg"
    },
    "stringer": {
      "label": "Stringer length",
      "description": "The diagonal of the total rise and total run: √(rise² + run²).",
      "format": "quantity",
      "unit": "in"
    },
    "firstCut": {
      "label": "First riser cut",
      "description": "The height to cut the bottom riser on the stringer: riser height − tread thickness.",
      "format": "quantity",
      "unit": "in"
    },
    "blondel": {
      "label": "2 × riser + tread",
      "description": "Blondel’s comfort check: twice the riser height plus the tread depth. About 24 to 25 in is comfortable.",
      "format": "quantity",
      "unit": "in"
    },
    "headroom": {
      "label": "Headroom",
      "description": "The vertical clearance under the edge of the floor opening, from the sloped line through the tread nosings.",
      "format": "quantity",
      "unit": "in"
    },
    "openingNeeded": {
      "label": "Opening for the required headroom",
      "description": "The shortest floor opening that gives the required headroom.",
      "format": "quantity",
      "unit": "in"
    },
    "code": {
      "label": "IRC R311.7 check",
      "description": "Whether the riser, tread, headroom and flight rise meet the IRC limits, and which do not.",
      "format": "text"
    }
  },
  "defaultAnswer": {
    "inputs": {
      "rise": 2.4383999999999997,
      "stepMode": "fixedRise",
      "riser": 0.17779999999999999,
      "fixedSteps": 14,
      "runMode": "individual",
      "run": 0.2794,
      "totalRun": 3.6576,
      "hasTread": true,
      "treadT": 0.038099999999999995,
      "hasHeadroom": true,
      "opening": 2.4383999999999997,
      "floorT": 0.2032,
      "headroom": 2.032
    },
    "outputs": {
      "risers": 14,
      "riserHeight": 0.17417142857142856,
      "treads": 13,
      "treadDepth": 0.2794,
      "totalRun": 3.6321999999999997,
      "angle": 0.5574310915759405,
      "stringer": 4.374776725731269,
      "firstCut": 0.13607142857142857,
      "blondel": 0.6277428571428572,
      "headroom": 1.3168415584415583,
      "openingNeeded": 3.5856333333333335,
      "code": "Check: headroom too low"
    },
    "text": "A total rise of 8 ft 0 in takes 14 risers of 6.86 in and treads of 11 in."
  },
  "examples": [
    {
      "given": {
        "rise": 2.4383999999999997,
        "stepMode": "fixedRise",
        "riser": 0.17779999999999999,
        "runMode": "individual",
        "run": 0.2794,
        "hasTread": true,
        "treadT": 0.038099999999999995,
        "hasHeadroom": true,
        "opening": 2.4383999999999997,
        "floorT": 0.2032,
        "headroom": 2.032
      },
      "expect": {
        "risers": 14,
        "riserHeight": 0.17417142857142856,
        "treads": 13,
        "totalRun": 3.6321999999999997,
        "stringer": 4.374776725731269,
        "firstCut": 0.13607142857142857,
        "headroom": 1.3168415584415583,
        "openingNeeded": 3.585633333333333,
        "code": "Check: headroom too low"
      },
      "source": "hand calculation in content.mdx: 96 ÷ 7 = 13.7 → 14 risers of 6.857 in; 13 treads × 11 = 143 in; √(96² + 143²) = 172.24 in; headroom 88 − (6.857 + 47 × 6.857 ÷ 11) = 51.84 in"
    },
    {
      "given": {
        "rise": 2.7432,
        "stepMode": "fixedSteps",
        "fixedSteps": 14,
        "runMode": "total",
        "totalRun": 3.302,
        "hasTread": false,
        "hasHeadroom": false
      },
      "expect": {
        "riserHeight": 0.19594285714285714,
        "treadDepth": 0.254,
        "angle": 0.6570749357116535,
        "blondel": 0.6458857142857143,
        "code": "Meets the limits"
      },
      "source": "hand calculation in content.mdx: 108 ÷ 14 = 7.714 in (under 7¾ in); 130 ÷ 13 = 10 in (the IRC minimum); arctan(7.714 ÷ 10) = 37.6°"
    },
    {
      "given": {
        "rise": 2.4383999999999997,
        "stepMode": "fixedSteps",
        "fixedSteps": 12,
        "runMode": "individual",
        "run": 0.2413,
        "hasTread": false,
        "hasHeadroom": false
      },
      "expect": {
        "riserHeight": 0.2032,
        "code": "Check: riser over 7¾ in; tread under 10 in"
      },
      "source": "IRC R311.7.5.1 (riser at most 7¾ in) and R311.7.5.2 (tread at least 10 in): 96 ÷ 12 = 8 in and 9.5 in both fail"
    }
  ],
  "sources": [],
  "related": [],
  "changelog": []
}
