Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions files/en-us/web/css/reference/properties/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ Standard properties defined by CSS specifications include the following:
- {{CSSxRef("page-break-inside")}}
- {{CSSxRef("page")}}
- {{CSSxRef("paint-order")}}
- {{CSSxRef("path-length")}}
- {{CSSxRef("perspective-origin")}}
- {{CSSxRef("perspective")}}
- {{CSSxRef("place-content")}} (shorthand)
Expand Down
183 changes: 183 additions & 0 deletions files/en-us/web/css/reference/properties/path-length/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
---
title: "`path-length` CSS property"
short-title: path-length
slug: Web/CSS/Reference/Properties/path-length
page-type: css-property
browser-compat: css.properties.path-length
sidebar: cssref
---

The **`path-length`** [CSS](/en-US/docs/Web/CSS) property specifies a total path length, in user units. This value is then used to calibrate the browser's distance calculations with those of the author, by scaling all distance computations using the ratio `path-length` / _(computed value of path length)_.

@hamishwillee hamishwillee Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's a user unit? Without a knowledge of user units this is quite abstract. It is hard to understand what is going on and more important, why this matters in any way, shape or form. Why would I use this? What does this scaling do for me that not having it would prevent?

MDN does not help - I think https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorials/SVG_from_scratch/Positions#what_are_pixels is probably just wrong in some respects. It is certainly inconsistent in its terminology and doesn't help with this case.

Anyway, I think the point is that some properties, such as stroke-dasharray, are specified in user units - in this case "units per dash". So the svg path length had some original calculated user units that results in some calculation of how many dashes there would normally be shown. Now we're saying you can use this property to specify what the length of the path should be, and that will be used to scale the calculations, and in this case change the number and length of dashes.

I'm really not sure what can be done here, or even if this is where things can/should be updated. But I am still confused :-( Consider this a "fat nit" - it would be nice if you can help people like me understand this here, but perhaps it is out of scope.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just assumed that a user unit was well-known to SVG folks.

Ye gods, that page you linked to is confusingly written. That definitely needs some sorting out at some point, but this PR is not the place to do it.

For now, I've added a short definition of what a user unit is to the path-length page itself. I'm not sure this is ideal, but it helps this particular case for now.

@hamishwillee hamishwillee Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a note that the added sentence is wrong and needs looking at.

But yes, I accept that it's too big a job to scope in this PR - though I would dearly like you to, because I suspect that SVG folks might not get this either - at least not from MDN. I'm not even sure "calibrate the browsers ..." is correct - certainly it isn't the point of this property - the "reason we need it".

At high level the concept is pretty clear - the SVG is defined in some arbitrary user units and then rendered in a viewport - which provides the scaling to real units. The path-length allows you to scale the effective length of a path element, which then forces other elements that are defined in terms of the user units to also scale. But how you work out what those units are, and why/when this is useful is not clear at all.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other problem is that without this it isn't possible to know what "calibrate the browsers ..." means. I.e. back to "practically, what is this for".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've trimmed this text down to:

The path-length CSS property specifies a total path length, in user units. All path computations are then scaled using the ratio path-length / (computed value of path length) — this includes text paths, animation paths, and various stroke operations.

This seems to make a bit more sense, but it still relies on understanding what a user unit is.


This can affect the browser's distance-along-a-path calculations and therefore the actual rendered lengths of paths — this includes text paths, animation paths, and various stroke operations.

The `path-length` property only applies to {{SVGElement("circle")}}, {{SVGElement("ellipse")}}, {{SVGElement("line")}}, {{SVGElement("path")}}, {{SVGElement("polygon")}}, {{SVGElement("polyline")}}, and {{SVGElement("rect")}} elements nested in an {{SVGElement("svg")}}.
Comment thread
hamishwillee marked this conversation as resolved.
Outdated

> [!NOTE]
> If present, the `path-length` CSS property overrides an SVG element's {{SVGAttr("pathLength")}} attribute.
> This property doesn't apply to SVG, HTML, or pseudo-elements other than those listed above.

## Syntax

```css
/* Keywords */
path-length: none;

/* <length> values */
path-length: 0;
path-length: 70;
path-length: 500;

/* Global values */
path-length: inherit;
path-length: initial;
path-length: revert;
path-length: revert-layer;
path-length: unset;
```

### Values

- `none`
- : No author path length is specified and the user agent's own computed path length is used for all path-related calculations.

- `<length>`
- : A non-negative unitless value representing an author-defined total path length, in user units.

## Formal definition

{{CSSInfo}}
Comment thread
hamishwillee marked this conversation as resolved.

## Formal syntax

{{csssyntax}}

## Examples

### Basic usage

This example defines a path and shows how to apply a path length to it using the `path-length` CSS property.

#### SVG

Our SVG defines a single curved {{SVGElement("path")}} element with a colored {{SVGAttr("stroke")}}. It includes a {{SVGAttr("stroke-dasharray")}} attribute that defines a regular dashed pattern for the stroke.

```html live-sample___basic-path-length live-sample___path-length-animation
<svg viewBox="0 0 600 200">
<path
d="M 30 100 C 150 20, 250 180, 380 100 S 520 20, 570 100"
fill="none"
stroke="#D85A30"
stroke-width="4"
stroke-dasharray="24 24"></path>
</svg>
```

#### CSS

We set a `path-length` value on the `<path>`:

```css live-sample___basic-path-length
path {
path-length: 500;
}
```

#### Results

{{EmbedLiveSample("basic-path-length", "100%", "230")}}

Setting a large `path-length` value results in the dashes becoming smaller and more frequent.

### Animating `path-length`

One major advantage of making `path-length` available as a CSS property is that you can apply standard CSS functionality such as [animations](/en-US/docs/Web/CSS/Guides/Animations) and [transitions](/en-US/docs/Web/CSS/Guides/Transitions) to it. This example builds on the previous one, showing how to animate a `path-length` with a CSS animation.

#### HTML and SVG

This example includes the same SVG `<path>` as the previous one. In addition, it includes an [`<input type="range">`](/en-US/docs/Web/HTML/Reference/Elements/input/range) element that can be used to change the value of `path-length` applied to the `<path>` at runtime. We also include an {{htmlelement("output")}} element to display the current slider value.

```html live-sample___path-length-animation
<div>
<label for="path-slider">Adjust path-length</label>
<input type="range" id="path-slider" min="0" max="800" value="200" />
<output>200</output>
</div>
```

#### CSS

On the {{cssxref(":root")}} element, we define a [CSS custom property](/en-US/docs/Web/CSS/Reference/Properties/--*) called `--path-length` and give it an initial value of `200`. We then set the `<path>` element's `path-length` value to the `--path-length` property, and set an {{cssxref("animation")}} on it that runs an infinite number of times and alternates between forwards and backwards.

```css live-sample___path-length-animation
:root {
--path-length: 200;
}

path {
path-length: var(--path-length);
animation: path-length-anim 2s alternate infinite ease-in-out;
}
```

```css hidden live-sample___path-length-animation
div {
position: fixed;
bottom: 0;
left: 0;
display: flex;
align-items: center;
}
```

Next, we define the {{cssxref("@keyframes")}} block for the animation — it animates the `path-length` property between the `--path-length` value and the `--path-length` value multiplied by `1.5`.

```css live-sample___path-length-animation
@keyframes path-length-anim {
from {
path-length: var(--path-length);
}

to {
path-length: calc(var(--path-length) * 1.5);
}
}
```

#### JavaScript

We start our script by grabbing references to the `<input type="range">`, `<output>`, and `:root` elements.

```js live-sample___path-length-animation
const slider = document.querySelector("input");
const output = document.querySelector("output");
const rootElem = document.querySelector(":root");
```

Next, we add an `input` event handler to the range slider so that, when its value is changed, the `<output>` element's `textContent` and the value of the `--path-length` custom property are set to equal the slider's new value.

```js live-sample___path-length-animation
slider.addEventListener("input", () => {
output.textContent = slider.value;
rootElem.style.setProperty("--path-length", slider.value);
});
```

#### Results

{{EmbedLiveSample("path-length-animation", "100%", "230")}}

Adjust the slider, and note how larger values result in a smaller dash size.

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- SVG {{SVGAttr("pathLength")}} attribute
- Presentation properties: {{cssxref("fill")}}, {{cssxref("clip-rule")}}, {{cssxref("color-interpolation-filters")}}, {{cssxref("fill-opacity")}}, {{cssxref("fill-rule")}}, {{cssxref("marker-end")}}, {{cssxref("marker-mid")}}, {{cssxref("marker-start")}}, `path-length`, {{cssxref("shape-rendering")}}, {{cssxref("stop-color")}}, {{cssxref("stop-opacity")}}, {{cssxref("stroke")}}, {{cssxref("stroke-dasharray")}}, {{cssxref("stroke-dashoffset")}}, {{cssxref("stroke-linecap")}}, {{cssxref("stroke-linejoin")}}, {{cssxref("stroke-miterlimit")}}, {{cssxref("stroke-opacity")}}, {{cssxref("stroke-width")}}, {{cssxref("text-anchor")}}, and {{cssxref("vector-effect")}}
Comment thread
hamishwillee marked this conversation as resolved.
Outdated
1 change: 1 addition & 0 deletions files/en-us/web/svg/reference/attribute/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ Most presentation attributes inherit when used as CSS properties (for example, {
- {{SVGAttr("mask-type")}}
- {{SVGAttr("opacity")}}
- {{SVGAttr("overflow")}}
- {{SVGAttr("pathLength")}}
- {{SVGAttr("pointer-events")}}
- {{SVGAttr("r")}}
- {{SVGAttr("rx")}}
Expand Down
7 changes: 7 additions & 0 deletions files/en-us/web/svg/reference/attribute/pathlength/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ You can use this attribute with the following SVG elements:
- {{SVGElement('polyline')}}
- {{SVGElement('rect')}}

> [!NOTE]
> As a presentation attribute, `pathLength` also has a CSS property counterpart: {{cssxref("path-length")}}. When both are specified, the CSS property takes priority.
Comment thread
hamishwillee marked this conversation as resolved.
Outdated

## Example

```css hidden
Expand Down Expand Up @@ -238,3 +241,7 @@ For {{SVGElement('rect')}}, `pathLength` lets authors specify a total length for
## Specifications

{{Specifications}}

## See also

- CSS {{cssxref("path-length")}} property
Loading