docs.rodeo

MDN Web Docs mirror

shape()

{{CSSRef}} {{SeeCompatTable}} 

The shape() CSS function is used to define a shape for the {{cssxref("clip-path")}}  and {{cssxref("offset-path")}}  properties. It combines an initial starting point with a series of shape commands that define the path of the shape. The shape() function is a member of the {{cssxref("<basic-shape>")}}  data type.

Syntax

/* <fill-rule> */
clip-path: shape(nonzero from 0 0, line to 10px 10px);

/* <move-command>, <line-command>, and close */
offset-path: shape(from 10px 10px, move by 10px 5px, line by 20px 40%, close);

/* <hvline-command> */
offset-path: shape(from 10px 10px, hline by 50px, vline to 5rem);

/* <curve-command> */
offset-path: shape(from 10px 10px, curve to 80px 80px via 160px 1px 20% 16px);

/* <smooth-command> */
offset-path: shape(from 10px 10px, smooth to 100px 50pt);

/* <arc-command> */
offset-path: shape(
  from 5% 0.5rem,
  arc to 80px 1pt of 10% ccw large rotate 25deg
);

/* Using a CSS math function */
offset-path: shape(
  from 5px -5%,
  hline to 50px,
  vline by calc(0% + 160px),
  hline by 70.5px,
  close,
  vline by 60px
);

clip-path: shape(
  evenodd from 10px 10px,
  curve to 60px 20% via 40px 0,
  smooth to 90px 0,
  curve by -20px 60% via 10% 40px 20% 20px,
  smooth by -40% -10px via -10px 70px
);

Parameters

Description

The shape() function allows you to define complex shapes. It is similar to the {{cssxref("basic-shape/path","path()")}}  shape function in several ways:

However, shape() offers several advantages over using path():

Formal syntax

{{csssyntax}} 

Examples

Using shape() to define a path

This example demonstrates how the shape() function can be used in the {{cssxref("offset-path")}}  property to define the shape of the path an element can follow.

The first shape, shape1, follows a cubic Bézier curved path defined by the curve to command. Next, the close command draws a straight line from the curve’s end point back to the initial point defined in the from command. Finally, shape1 moves to its new position at 0px 150px and then proceeds along a horizontal line.

The second shape, shape2, initially follows a horizontal line, then moves back to its starting position at 50px 90px. Next, it follows a vertical line before closing the path back to the initial point.

Both shapes start with their original colors and gradually transition to hotpink by the end of the move animation, reverting to their initial color as the animation restarts. This cyclic color change provides you a visual cue about the animation’s progression and restart.

<div class="container">
  Using <code>&lt;curve-command&gt;</code>
  <div class="shape shape1">>></div>
</div>

<div class="container">
  Using <code>&lt;move-command&gt;</code> and
  <code>&lt;hvline-command&gt;</code>
  <div class="shape shape2">>></div>
</div>
body {
  align-items: center;
  justify-content: center;
  display: flex;
}

.container {
  position: relative;
  display: inline-block;
  width: 250px;
  height: 250px;
  border: 2px dotted green;
  margin: 20px;
}

@supports not (offset-path: shape(from 0 0, move to 0 0)) {
  .container {
    display: none;
  }
  body::after {
    content: "Your browser doesn't support the `shape()` function yet.";
  }
}
.shape {
  width: 50px;
  height: 50px;
  background: #2bc4a2;
  position: absolute;
  text-align: center;
  line-height: 50px;
  animation: move 6s infinite linear;
}

.shape1 {
  offset-path: shape(
    from 30% 60px,
    curve to 180px 180px via 90px 190px,
    close,
    move by 0px 150px,
    hline by 40%
  );
}

.shape2 {
  offset-path: shape(
    from 50px 90px,
    hline to 8em,
    move to 50px 90px,
    vline by 20%,
    close
  );
}

@keyframes move {
  0% {
    offset-distance: 0%;
  }
  100% {
    offset-distance: 100%;
    background-color: hotpink;
  }
}

Result

{{EmbedLiveSample('Using shape() to define a path', '100%', 300)}} 

Using shape() to define the visible part of an element

This example demonstrates how the shape() function can be used in the {{cssxref("clip-path")}}  property to create different shapes for the clipping region. The first shape (shape1) uses a triangle defined by straight lines. The second shape (shape2) includes curves and smooth transitions; it also illustrates the use of the <move-command> after the close command, which adds a rectangular shape to the clipping region.

<div class="container">
  <div class="shape shape1"></div>
</div>

<div class="container">
  <div class="shape shape2"></div>
</div>
body {
  align-items: center;
  justify-content: center;
  display: flex;
}

.container {
  position: relative;
  display: inline-block;
  width: 200px;
  height: 200px;
  margin: 20px;
  background-color: lightgray;
}

@supports not (clip-path: shape(from 0 0, move to 0 0)) {
  .container {
    display: none;
  }
  body::after {
    content: "Your browser doesn't support the `shape()` function yet.";
  }
}
.shape {
  width: 100%;
  height: 100%;
  background: #2bc4a2;
  position: absolute;
  text-align: center;
  line-height: 50px;
}

/* Triangular clipping region */
.shape1 {
  clip-path: shape(from 0% 0%, line to 100% 0%, line to 50% 100%, close);
}

/* Clipping region with curves and smooth transitions and a box */
.shape2 {
  clip-path: shape(
    from 10px 10px,
    curve to 60px 20% via 40px 0,
    smooth to 90px 0,
    curve by -20px 60% via 10% 40px 20% 20px,
    smooth by -40% -10px via -10px 70px,
    close,
    move to 100px 100px,
    hline by 50px,
    vline by 50px,
    hline by -50px,
    close
  );
}

Result

{{EmbedLiveSample('Using shape() to define the visible part of an element', '100%', 300)}} 

Specifications

{{Specifications}} 

Browser compatibility

{{Compat}} 

See also

In this article

View on MDN