CSS ray() Function

The CSS ray() function defines a straight-line motion path extending from a starting point in a specified direction.

It is used with the offset-path property to position and animate elements along a ray. The function supports an angle, optional size keywords, a containment setting, and a starting position.

Syntax

ray(angle)
ray(angle size)
ray(angle contain)
ray(angle at position)
ray(angle size contain at position)

The angle is required. The size, contain keyword, and starting position are optional.

For example:

offset-path: ray(45deg);
offset-path: ray(90deg closest-side);
offset-path: ray(180deg farthest-side);
offset-path: ray(45deg contain);
offset-path: ray(90deg closest-side contain at center);

The ray() function produces a CSS <ray()> value that can be used as a motion path.

Unlike path(), which uses SVG path commands, ray() defines a straight path using an angle and optional settings.

Parameters

The ray() function accepts one required argument and several optional settings.

Parameter Description
angle Required. Specifies the direction of the ray using an angle value.
size Optional. Determines the ray's length using a size keyword.
contain Optional. Adjusts the path length to help keep the moving element within the reference boundary.
at position Optional. Specifies the ray's starting point using position values.

For example:

ray(45deg farthest-side contain at 50% 50%)

This defines a ray pointing diagonally toward the upper-right direction, with its length based on the farthest side and adjusted for containment.

The starting position is the center of the reference box.

Optional components can be combined in different valid orders, but the at keyword must be followed by a valid position.

How It Works

The ray() function creates a straight path beginning at a defined point and extending in the direction specified by its angle.

For example:

.moving-element {
  offset-path: ray(90deg closest-side);
}

The ray extends horizontally toward the right.

The offset-distance property determines where the element is positioned along that path.

For example:

.moving-element {
  offset-path: ray(90deg closest-side);
  offset-distance: 50%;
}

This positions the element halfway along the ray's calculated length.

The path's length depends on the selected size keyword and its reference box.

By itself, ray() does not animate an element. Motion requires changing a related property such as offset-distance.

Ray Angles

The angle determines the direction in which the ray extends.

In the ray() function, 0 degrees points upward and positive angles rotate clockwise.

Angle Direction
0degUp
45degUpper right
90degRight
135degLower right
180degDown
225degLower left
270degLeft
315degUpper left

For example:

offset-path: ray(0deg);
offset-path: ray(90deg);
offset-path: ray(180deg);
offset-path: ray(270deg);

Angles can also use units such as turn, rad, and grad.

For example:

offset-path: ray(0.25turn);
offset-path: ray(1.5708rad);

Both expressions describe a direction approximately equivalent to 90 degrees.

Size Keywords

Size keywords control the distance the ray extends from its starting point.

Keyword Description
closest-side Uses the distance from the starting point to the nearest side of the reference box.
farthest-side Uses the distance from the starting point to the farthest side of the reference box.
closest-corner Uses the distance from the starting point to the nearest corner.
farthest-corner Uses the distance from the starting point to the farthest corner.
sides Uses the intersection of the ray with the reference box's boundary.

For example:

offset-path: ray(45deg closest-side);
offset-path: ray(45deg farthest-side);
offset-path: ray(45deg closest-corner);
offset-path: ray(45deg farthest-corner);
offset-path: ray(45deg sides);

The closest-side keyword is the default when no size is specified.

Unlike sides, the other size keywords calculate lengths based on distances to sides or corners rather than necessarily ending at the boundary along the ray's direction.

The reference box and starting position both affect the resulting length.

The contain Keyword

The optional contain keyword adjusts the ray's length to account for the dimensions of the element moving along the path.

For example:

.moving-element {
  offset-path: ray(90deg sides contain);
}

The contain keyword reduces the path length to help keep the moving element within the reference box when it reaches the end of the ray.

Without contain, the element's reference point can reach the end of the path while part of the element extends beyond the boundary.

For example:

offset-path: ray(90deg sides);
offset-path: ray(90deg sides contain);

The second declaration accounts for the element's size when calculating the usable path length.

This is useful for motion effects that should remain inside a defined area.

The keyword does not apply clipping or prevent all possible overflow from other transforms.

Starting Position

The at keyword specifies where the ray begins.

For example:

offset-path: ray(90deg at center);
offset-path: ray(90deg at top left);
offset-path: ray(180deg at 50% 20%);
offset-path: ray(45deg at 100px 50px);

The position can use keywords, percentages, lengths, or compatible combinations.

For example:

offset-path: ray(90deg sides at 25% 50%);

This creates a ray beginning one-quarter across the reference box and halfway down its height.

The ray extends toward the right boundary.

If no at position is supplied, the starting point is determined by the motion-path positioning rules, including the offset-position property.

Use an explicit position when the ray must begin at a predictable location.

Using ray() with offset-path

The offset-path property defines the path an element follows.

For example:

.moving-element {
  offset-path: ray(90deg sides);
}

This creates a horizontal ray pointing toward the right.

The offset-distance property controls the element's position along the path:

.moving-element {
  offset-path: ray(90deg sides);
  offset-distance: 50%;
}

The element is positioned halfway along the calculated ray.

The offset-rotate property controls its orientation.

For example:

.moving-element {
  offset-path: ray(90deg sides);
  offset-distance: 50%;
  offset-rotate: 0deg;
}

This keeps the element at a fixed orientation instead of automatically rotating it to follow the path direction.

Using offset-distance

The offset-distance property determines how far an element moves along the ray.

For example:

.moving-element {
  offset-path: ray(90deg sides);
  offset-distance: 0%;
}

The element begins at the start of the ray.

Changing the distance moves it farther along the path:

offset-distance: 0%;
offset-distance: 25%;
offset-distance: 50%;
offset-distance: 75%;
offset-distance: 100%;

Percentages are calculated relative to the ray's length.

Length values can also be used:

.moving-element {
  offset-path: ray(90deg sides);
  offset-distance: 100px;
}

This places the element 100 pixels along the ray from its starting point.

Animating offset-distance creates movement along the defined direction.

Using offset-rotate

The offset-rotate property controls how an element is oriented while following a motion path.

For example:

.moving-element {
  offset-path: ray(45deg sides);
  offset-distance: 50%;
  offset-rotate: auto;
}

The auto keyword aligns the element's orientation with the direction of the path.

A fixed angle can be used instead:

.moving-element {
  offset-path: ray(45deg sides);
  offset-distance: 50%;
  offset-rotate: 0deg;
}

This keeps the element at its original orientation.

An additional rotation can also be combined with automatic orientation:

offset-rotate: auto 90deg;

This adds a 90-degree rotation relative to the path direction.

Use automatic rotation for directional objects and a fixed rotation when the element should remain upright.

ray() vs. path()

The ray() and path() functions both define CSS motion paths, but they use different methods.

Feature ray() path()
Path type Straight line Lines and curves
Syntax Angle and optional settings SVG path commands
Length Calculated from a reference box Determined by path coordinates
Starting point Position keywords or coordinates SVG path starting coordinates
Typical use Directional movement Complex motion paths

For example, a straight ray:

offset-path: ray(90deg sides);

A straight SVG path:

offset-path: path("M 0 0 L 200 0");

Both can produce horizontal movement, but ray() calculates its length relative to a reference box.

The path() function is more appropriate when a motion path requires curves or several connected segments.

Example

This example positions three elements along rays pointing in different directions.

HTML:

<div class="ray-demo">
  <div class="ray-demo-item ray-demo-up">Up</div>
  <div class="ray-demo-item ray-demo-right">Right</div>
  <div class="ray-demo-item ray-demo-down">Down</div>
</div>

CSS:

.ray-demo {
  position: relative;
  height: 260px;
  background-color: #f1f3f5;
  overflow: hidden;
}
.ray-demo-item {
  position: absolute;
  top: 50%;
  left: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 40px;
  margin: -20px 0 0 -30px;
  background-color: #0066cc;
  color: #ffffff;
  font-weight: bold;
  offset-distance: 80px;
  offset-rotate: 0deg;
}
.ray-demo-up {
  offset-path: ray(0deg);
}
.ray-demo-right {
  offset-path: ray(90deg);
  background-color: #008577;
}
.ray-demo-down {
  offset-path: ray(180deg);
  background-color: #b45309;
}
Browser Result
Up
Right
Down

Each element uses a different ray angle but the same offset-distance of 80px.

The offset-rotate property keeps the labels upright.

In browsers without ray() support, the elements remain near their original positioned location.

Animation Example

This example animates an element along a horizontal ray using offset-distance.

HTML:

<div class="ray-animation-demo">
  <div class="ray-animation-item"></div>
</div>

CSS:

.ray-animation-demo {
  position: relative;
  height: 120px;
  background-color: #f1f3f5;
  overflow: hidden;
}
.ray-animation-item {
  position: absolute;
  top: 50%;
  left: 20px;
  width: 40px;
  height: 40px;
  margin-top: -20px;
  border-radius: 50%;
  background-color: #0066cc;
  offset-path: ray(90deg sides contain);
  offset-distance: 0%;
  offset-rotate: 0deg;
  animation: ray-move 3s ease-in-out infinite alternate;
}
@keyframes ray-move {
  from {
    offset-distance: 0%;
  }
  to {
    offset-distance: 100%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .ray-animation-item {
    animation: none;
  }
}
Browser Result

In supporting browsers, the circle moves along the ray and then returns to its starting point.

The alternate animation direction reverses the movement after each iteration.

The reduced-motion media query disables the animation when the user requests less motion.

Common Uses

The ray() function is useful for defining straight motion paths that depend on a direction and reference box.

Use Description
Directional animation Move elements along a straight line at a specified angle.
Radial positioning Position decorative elements outward from a starting point.
Responsive motion Calculate motion paths relative to a reference box.
Interface effects Create directional movement for icons and indicators.
Contained movement Adjust a path to account for the moving element's size.

For example:

.move-right {
  offset-path: ray(90deg sides);
}
.move-up {
  offset-path: ray(0deg closest-side);
}
.move-diagonal {
  offset-path: ray(135deg farthest-corner);
}

Each declaration defines a different direction or path length.

The element's actual position is determined by the accompanying motion-path properties.

Limitations

The ray() function has several important rules and limitations.

  • An angle is required.
  • The function defines a straight path rather than a curved path.
  • Only supported size keywords can be used to determine the ray's length.
  • The contain keyword adjusts path length but does not clip the element.
  • The at keyword requires a valid position.
  • The function does not animate an element by itself.
  • Motion requires properties such as offset-distance and CSS animations or transitions.
  • The calculated path depends on the reference box and positioning rules.
  • Browser support is more limited than basic CSS transforms.
  • Fallback styling is recommended for essential layouts and interactions.

For example, this is valid:

offset-path: ray(45deg closest-side);

The following is invalid because the required angle is missing:

offset-path: ray(closest-side);

The following is invalid because at has no position:

offset-path: ray(45deg at);

Use path() or shape() when a motion path requires curves or multiple connected segments.

Browser Support

The CSS ray() function has Limited availability and is not Baseline across all major browsers.

Support for ray() may differ from support for other motion-path features, including offset-path with path().

For example:

.moving-element {
  offset-path: none;
  offset-path: ray(90deg sides);
}

Browsers that support ray() use the ray as the motion path. Unsupported browsers retain the preceding valid declaration.

Feature detection can also be used:

@supports (offset-path: ray(90deg)) {
  .moving-element {
    offset-path: ray(90deg sides);
  }
}

The @supports rule checks whether the browser accepts the specified declaration.

For current compatibility information, visit Can I Use? and search for CSS ray() or CSS Motion Path.

Specifications

The ray() function is defined in the Motion Path Module Level 1 .

The specification defines the ray's direction, size keywords, containment behavior, and use with CSS motion paths.

Related CSS features include offset-path, offset-distance, offset-rotate, offset-position, and the path() function.