A 41-pixel base does not silently round to 40 pixels when you use the CSS Triangle Generator. The generator splits odd totals into floor and ceiling border widths — for example, 20 pixels and 21 pixels on a 41-pixel base — so that the painted dimension matches the number you typed. This matters because Chromium can quantize two 20.5-pixel borders down to 20 pixels each, which would quietly shrink the shape by one full pixel and leave a subtle gap or jagged edge at the base. The generator's implementation pre-splits the math before writing the CSS, exposes each longhand border explicitly, and uses the same derived values in both the live preview and the copied code. An odd width, height, or base is preserved as a deliberate one-pixel asymmetry instead of being collapsed into a single rounded value that the browser can drop. The technique works for any odd total in the supported range, from 10 to 300 pixels, and produces triangles whose measured base matches the requested base down to the last pixel. This article walks through the pixel quantization problem, the floor-and-ceiling technique itself, and exactly how to generate a triangle whose dimensions stay exact even when the base is odd.

how does an odd base dimension stay exact when i generate css triangle
Why an Odd Base Dimension Stays Exact in a CSS Triangle

The Pixel Quantization Problem

A CSS border is painted in whole pixels by the browser. When a generator assigns a fractional value such as 20.5 pixels to a border, the rendering engine has to decide whether to round up to 21 or down to 20, and it does not always pick the same answer on both sides of an axis. If a generator writes two transparent side borders at 20.5 pixels each and expects the resulting base to come out to 41 pixels, Chromium can round both borders down to 20 pixels, which silently shrinks the painted dimension by a full pixel. The visible result is a triangle that is one pixel narrower than the number you entered, plus a small asymmetry at the base where 20 and 20 meet a colored border that was supposed to be 41.

This behavior is documented in the CSS Backgrounds and Borders specification, which defines how border widths are serialized and rendered (W3C: CSS Backgrounds and Borders Level 3). The MDN background-and-borders guide also notes that transparent colors and border widths interact with the box model in non-obvious ways (MDN: CSS backgrounds and borders). The takeaway for triangle generation is simple: never assume that two identical fractional borders will be summed faithfully by every rendering engine.

How the Floor and Ceiling Split Works

The floor-and-ceiling split avoids that assumption by replacing one of the fractional halves with an integer one pixel larger than the other. Take a 41-pixel base as the worked example. Rather than writing two 20.5-pixel borders, the generator writes one 20-pixel border and one 21-pixel border. The arithmetic is 20 plus 21, which equals 41, the original total. The one-pixel asymmetry is invisible in the rendered shape because both transparent borders meet the same colored border at the apex and the base line; the human eye does not perceive a 20-versus-21 split on a transparent edge.

Even totals split exactly in half because floor and ceiling collapse to the same integer. A 40-pixel base becomes two 20-pixel borders, and the math reads as a clean 50/50 division. The generator applies the rule inside whole-pixel space (the inputs themselves must be integers between 10 and 300), so no fractional borders ever appear in the output CSS.

The colored border, which forms the pointing side of the triangle, is written at the full height or width that was selected. The transparent side borders never paint a color, so their only role is to occupy space and create the slope. The visible shape is therefore determined by the colored border's dimension, while the base dimension is determined by the sum of the two transparent borders. As long as that sum is exact, the base is exact.

Generate an Odd-Base Triangle That Stays Exact

Here is the concrete procedure for producing a triangle whose odd base stays exact in the rendered output. The steps use the CSS Triangle Generator interface directly.

  1. Pick a direction (up, down, left, or right) from the available controls. The direction decides which border is colored and which two are transparent.
  2. Type whole-number values into the width and height fields. Whole values between 10 and 300 are accepted; decimals are rejected by the generator.
  3. If you want an odd base, type an odd number into the dimension that controls the base. For a vertical triangle (up or down) the base is the selected width; for a horizontal triangle (left or right) the base is the selected height.
  4. Enter a six-digit HEX color in the format #RRGGBB. Lowercase and uppercase letters are both accepted and normalized to lowercase in the output.
  5. Inspect the live preview at the approximate size and background where the triangle will sit. The preview uses the same longhand border declarations that appear in the copied CSS, so what you see is what ships.
  6. Copy CSS and Copy HTML separately using the two clipboard buttons. Each button asks for clipboard permission on its own and reports a success message naming the copied format. If the browser denies clipboard access, both code blocks remain visible for manual selection.
  7. Decide whether aria-hidden is appropriate for the destination. The default snippet uses aria-hidden="true" because the triangle is decorative. If the shape communicates meaning or acts as a control, do not rely on that attribute alone — add visible text or an accessible label to the surrounding semantic element.
  8. Rename the default class if it would collide with an existing stylesheet, and update both the CSS and the HTML output so the rename stays in sync.

How Dimensions Map to Borders Across All Four Directions

The floor-and-ceiling rule behaves differently depending on whether the triangle is vertical or horizontal. The table below summarizes which borders are colored, which are transparent, and which dimension is split.

Direction Colored border Transparent borders Base dimension (split) Pointing dimension (full)
Up Bottom Left, right Selected width Selected height
Down Top Left, right Selected width Selected height
Left Right Top, bottom Selected height Selected width
Right Left Top, bottom Selected height Selected width

The base is always split across two transparent borders using floor and ceiling. The pointing side is always a single colored border set to the full selected dimension. For a vertical triangle, the transparent left and right borders add up to the selected width. For a horizontal triangle, the transparent top and bottom borders add up to the selected height.

For a deeper walkthrough of the up, down, left, and right cases, the four-direction CSS Triangle border recipe spells out each border declaration line by line. To pick sensible width and height values before generating, the width and height guide pairs each direction with the inputs that produce a recognizable shape.

Checking the Live Preview Against Your Destination

The live preview confirms the border geometry, not the full layout, theming, or accessibility behavior of the component you place the triangle inside. Verify the painted dimension by measuring the rendered element in browser dev tools: the content box should be 0 by 0, while the painted area should match the base plus the pointing dimension. If the numbers do not match, check that no other CSS rule is overriding the border widths or colors.

Rasterization can still vary with zoom and device pixel ratio, so test at 200 percent zoom, at a forced-colors setting, and at common mobile widths. A triangle used next to text should also be checked against light and dark themes rather than assumed to inherit sufficient contrast — the Color Contrast Checker can confirm that the HEX you selected meets WCAG thresholds against the surrounding background. The painted HEX is opaque by default, so plan for both themes if the surrounding component supports theming.

If the destination stack uses design tokens, the literal HEX can be replaced after copying with a CSS variable, gradient, or currentColor keyword. The generator does not emit those syntaxes directly because it is focused on solid border triangles, but the transparent side borders must remain transparent — switching a transparent border to a colored value would collapse the triangle back into a rectangle.

When a Border Triangle Is Not the Right Shape

A border triangle is small, fast, and predictable, but it cannot do everything. It cannot directly produce a rounded tip, a curved edge, a hollow outline, a gradient fill, a drop shadow, or an arbitrary polygon — every one of those shapes requires SVG or a clip-path built from curves, and the generator does not attempt to fake them. Border triangles also have a measurable content box of zero, which makes layout, transforms, hit testing, outlines, overflow, and alignment less intuitive than working with an SVG that has an explicit viewBox.

For a single decorative arrow or separator, the border approach is the right choice. For a state-bearing indicator, a navigation control, or any shape that needs more than a single straight edge, switch to SVG or clip-path and test browser support in the intended environment. The generator will not pretend to produce those shapes, and trying to bend its output toward them usually costs more time than picking the right technique from the start.