shape()

可用性有限

此特性不是基線特性,因為它在一些最廣泛使用的瀏覽器中不起作用。

shape() CSS 函式用於為 clip-pathoffset-path 屬性定義形狀。它將一個初始起點與一系列定義形狀路徑的形狀命令相結合。shape() 函式是 <basic-shape> 資料型別的一員。

語法

css
/* <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 with 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% with 40px 0,
  smooth to 90px 0,
  curve by -20px 60% with 10% 40px / 20% 20px,
  smooth by -40% -10px with -10px 70px,
  close
);

引數

<fill-rule> 可選

指定如何填充形狀的重疊區域。可能的值包括:

  • nonzero:如果從某點繪製的射線穿過從左到右的路徑段多於從右到左的路徑段,從而導致非零計數,則該點被認為在形狀內部。這是省略 <fill-rule> 時的預設值。

  • evenodd:如果從某點繪製的射線穿過奇數個路徑段,則該點被認為在形狀內部。這意味著射線每次進入形狀時,並沒有退出相等的次數,表明進入次數為奇數且沒有相應的退出。

警告:<fill-rule>offset-path 中不受支援,使用它會使該屬性無效。

from <coordinate-pair>

將第一個 <shape-command> 的起點定義為一對座標,該座標從參考盒的左上角開始測量。座標以空格分隔的 <x> <y> <length-percentage> 值的形式指定,分別表示左偏移和上偏移。百分比值分別相對於元素參考盒的寬度和高度。在此引數後新增一個逗號。

<shape-command>

指定一個或多個用逗號分隔的命令列表,這些命令定義了形狀,其語法類似於 SVG 路徑命令。命令包括 <move-command><line-command><hv-line-command><curve-command><smooth-command><arc-command>close。每個命令的起點是前一個命令的終點,形狀的第一個點由 from <coordinate-pair> 引數定義。

大多數形狀命令的語法是一個提供指令的關鍵字(如 moveline),後跟 byto 關鍵字,以及一組座標。

by:表示 <coordinate-pair> 相對於命令的起點(“相對”值)。

to:表示 <coordinate-pair> 相對於參考盒的左上角(“絕對”值)。

備註: 如果 <coordinate-pair> 中的座標被指定為百分比,則該值是相對於參考盒各自的寬度或高度計算的。

可以指定以下 <shape-command><move-command><line-command><hv-line-command><curve-command><smooth-command><arc-command>close

<move-command>:指定為 move [by | to] <coordinate-pair>。此命令向形狀命令列表中新增一個移動到(MoveTo)命令。它不繪製任何東西,而是為下一個命令指定起始位置。byto 關鍵字分別指定 <coordinate-pair> 點是相對的還是絕對的。如果 <move-command> 跟在 close 命令之後,它將標識下一個形狀或子路徑的起點。

<line-command>:指定為 line [by | to] <coordinate-pair>。此命令向形狀命令列表中新增一個畫線到(LineTo)命令。它從命令的起點到終點繪製一條直線。byto 關鍵字分別指定由 <coordinate-pair> 指定的終點是相對的還是絕對的。

<hv-line-command>:指定為 [hline | vline] [by | to] <length-percentage>。此命令向形狀命令列表中新增一個水平(hline)或垂直(vline)的畫線到(LineTo)命令。使用 hline 時,從命令的起點繪製一條水平線 to(到)或 by(偏移)由 <length-percentage> 定義的 x 位置。使用 vline 時,從命令的起點繪製一條垂直線 to(到)或 by(偏移)由 <length-percentage> 定義的 y 位置。byto 關鍵字分別確定終點是相對的還是絕對的。此命令等同於 <line-command>,其中一個座標值由單個 <length-percentage> 設定,而另一個座標值與其起始命令保持不變。

<curve-command>:指定為 curve [by | to] <coordinate-pair> with <coordinate-pair> [/ <coordinate-pair>]。此命令向形狀命令列表中新增一個貝塞爾曲線命令byto 關鍵字分別確定由第一個 <coordinate-pair> 指定的曲線終點是相對的還是絕對的。with 關鍵字指定貝塞爾曲線的控制點。

  • 如果只提供一個 <coordinate-pair>,該命令將繪製一條二次貝塞爾曲線,該曲線由三個點(起點、控制點和終點)定義。
  • 如果提供了兩個 <coordinate-pair> 值,該命令將繪製一條三次貝塞爾曲線,該曲線由四個點(起點、兩個控制點和終點)定義。

<smooth-command>:指定為 smooth [by | to] <coordinate-pair> [with <coordinate-pair>]。此命令向形狀命令列表中新增一個平滑的貝塞爾曲線命令byto 關鍵字分別確定由第一個 <coordinate-pair> 指定的曲線終點是相對的還是絕對的。

  • 如果省略 with <coordinate-pair>,該命令將繪製一條平滑的二次貝塞爾曲線,該曲線使用前一個控制點和當前端點來定義曲線。
  • 如果包含可選的 with 關鍵字,它將透過 <coordinate-pair> 指定曲線的控制點,繪製一條由前一個控制點、當前控制點和當前端點定義的平滑三次貝塞爾曲線。

平滑曲線確保了形狀的連續過渡,而二次曲線則不然。平滑二次曲線使用單個控制點保持無縫過渡,而平滑三次曲線則使用兩個控制點提供更精細的過渡。

<arc-command>:指定為 arc [by | to] <coordinate-pair> of <length-percentage> [<length-percentage>] [<arc-sweep> | <arc-size> | rotate <angle>]。此命令向形狀命令列表中新增一個橢圓弧曲線命令。它在起點和終點之間繪製一個橢圓弧。byto 關鍵字分別確定由第一個 <coordinate-pair> 指定的曲線終點是相對的還是絕對的。

橢圓弧曲線命令定義了兩個可能的橢圓,它們都與起點和終點相交,並且每個橢圓都可以順時針或逆時針繪製,從而根據弧的大小、方向和角度產生四種可能的弧。of 關鍵字指定了弧所在的橢圓的大小:第一個 <length-percentage> 提供橢圓的水平半徑,第二個 <length-percentage> 提供垂直半徑。

指定以下引數以選擇使用四條弧中的哪一條:

  • <arc-sweep>:指示所需的弧是沿橢圓順時針(cw)還是逆時針(ccw)繪製的弧。如果省略,則預設為 ccw
  • <arc-size>:指示所需的弧是兩條弧中較大(large)還是較小(small)的一條。如果省略,則預設為 small
  • <angle>:指定橢圓相對於 x 軸旋轉的角度,以度為單位。正角度使橢圓順時針旋轉,負角度使其逆時針旋轉。如果省略,則預設為 0deg

特殊情況處理如下:

  • 如果只提供一個 <length-percentage>,則水平和垂直半徑都使用相同的值,從而有效地建立一個圓形。在這種情況下,<arc-size><angle> 沒有影響。
  • 如果任一半徑為零,則該命令等同於到終點的 <line-command>
  • 如果任一半徑為負,則使用其絕對值。
  • 如果水平和垂直半徑所描述的橢圓不夠大,無法同時與起點和終點相交(在按指定的 <angle> 旋轉後),則半徑會按比例均勻放大,直到橢圓剛好足夠大,可以與兩個點相交。
  • 如果弧的起點和終點恰好位於橢圓的相對兩側,則只有一個可能的橢圓和兩條可能的弧。在這種情況下,<arc-sweep> 指定要選擇的弧,而 <arc-size> 沒有影響。

close:向形狀命令列表中新增一個閉合路徑(ClosePath)命令,從當前位置(上一個命令的終點)到 from <coordinate-pair> 引數中定義的路徑的第一個點繪製一條直線。要閉合形狀而不繪製線條,請在 close 命令之前包含一個帶有起始座標的 <move-command>。如果 close 命令緊跟著一個 <move-command>,它將定義下一個形狀或子路徑的起點。

描述

shape() 函式允許你定義複雜的形狀。它在幾個方面與 path() 形狀函式相似:

  • shape() 函式中的 <fill-rule> 引數與 path() 函式中的相同引數完全一樣。
  • shape() 函式需要指定一個或多個 <shape-command>,其中每個命令都使用一個底層的路徑命令,例如MoveToLineToClosePath

然而,與使用 path() 相比,shape() 提供了幾個優勢:

  • shape() 使用標準的 CSS 語法,使其更容易在樣式表中直接建立和修改形狀。相比之下,path() 使用 SVG path 語法,對於不熟悉 SVG 的人來說不太直觀。
  • shape() 支援多種 CSS 單位,包括百分比、remem。而 path() 將形狀定義為單個字串,且單位僅限於 px
  • shape() 還允許使用 CSS 數學函式,如 calc()max()abs(),在定義形狀時提供了更多的靈活性。

正式語法

<shape()> = 
shape( <'fill-rule'>? from <position> , <shape-command># )

<fill-rule> =
nonzero |
evenodd

<position> =
<position-one> |
<position-two> |
<position-four>

<shape-command> =
<move-command> |
<line-command> |
close |
<horizontal-line-command> |
<vertical-line-command> |
<curve-command> |
<smooth-command> |
<arc-command>

<position-one> =
left |
center |
right |
top |
bottom |
x-start |
x-end |
y-start |
y-end |
block-start |
block-end |
inline-start |
inline-end |
<length-percentage>

<position-two> =
[ left | center | right | x-start | x-end ] && [ top | center | bottom | y-start | y-end ] |
[ left | center | right | x-start | x-end | <length-percentage> ] [ top | center | bottom | y-start | y-end | <length-percentage> ] |
[ block-start | center | block-end ] && [ inline-start | center | inline-end ] |
[ start | center | end ]{2}

<position-four> =
[ [ left | right | x-start | x-end ] <length-percentage> ] && [ [ top | bottom | y-start | y-end ] <length-percentage> ] |
[ [ block-start | block-end ] <length-percentage> ] && [ [ inline-start | inline-end ] <length-percentage> ] |
[ [ start | end ] <length-percentage> ]{2}

<length-percentage> =
<length> |
<percentage>

示例

使用 shape() 定義路徑

此示例演示瞭如何在 offset-path 屬性中使用 shape() 函式來定義元素可以遵循的路徑形狀。

第一個形狀 shape1 遵循由 curve to 命令定義的立方貝塞爾曲線路徑。接下來,close 命令從曲線的終點畫一條直線回到 from 命令中定義的初始點。最後,shape1 移動到其新位置 0px 150px,然後沿著一條水平線前進。

第二個形狀 shape2 最初沿著一條水平線,然後移動回其起始位置 50px 90px。接下來,它沿著一條垂直線前進,然後閉合路徑回到初始點。

兩個形狀都以其原始顏色開始,並在 move 動畫結束時逐漸過渡到 hotpink,在動畫重新開始時恢復其初始顏色。這種迴圈的顏色變化為你提供了關於動畫進展和重新啟動的視覺提示。

css
.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 with 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;
  }
}

結果

使用 shape() 定義元素的可見部分

此示例演示瞭如何在 clip-path 屬性中使用 shape() 函式為剪下區域建立不同的形狀。第一個形狀(shape1)使用由直線定義的三角形。第二個形狀(shape2)包括曲線和平滑過渡;它還演示了在 close 命令之後使用 <move-command>,這會在剪下區域中新增一個矩形形狀。

css
.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);
}

/* A Heart clipping region using curve and arc transitions
   and a box using hline and vline transitions */
.shape2 {
  clip-path: shape(
    from 20px 70px,
    arc to 100px 70px of 1% cw,
    arc to 180px 70px of 1% cw,
    curve to 100px 190px with 180px 130px,
    curve to 20px 70px with 20px 130px,
    close,
    move to 150px 150px,
    hline by 40px,
    vline by 40px,
    hline by -40px,
    close
  );
}

結果

規範

規範
CSS 形狀模組 Level 2
# shape-function

瀏覽器相容性

另見