-
Notifications
You must be signed in to change notification settings - Fork 759
[css-shapes-2] Add a detailed example for shape()
#11548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -318,7 +318,7 @@ The ''shape()'' Function</h4> | |
| the command's starting point, the command's end point, or the [=reference box=], respectively. | ||
| If such component is not provided, the <<coordinate-pair>> is relative to the segment's start. | ||
|
|
||
| <dt><dfn><<arc-command>></dfn> = <dfn value>arc</dfn> <<command-end-point>> [[of <<length-percentage>>{1,2}] && <<arc-sweep>>? && <<arc-size>>? && rotate <<angle>>? ] | ||
| <dt><dfn><<arc-command>></dfn> = <dfn value>arc</dfn> <<command-end-point>> [[of <<length-percentage>>{1,2}] && <<arc-sweep>>? && <<arc-size>>?|| rotate <<angle>>? ] | ||
| <dd> | ||
| Add an <a href="https://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands">elliptical arc</a> command | ||
| to the list of path data commands, | ||
|
|
@@ -406,6 +406,127 @@ The ''shape()'' Function</h4> | |
| which affects how line-joins and line-caps are rendered. | ||
| </dl> | ||
|
|
||
| <h5 id=shape-examples>Using ''shape()'' to create responsive, parametric speech bubble</h5> | ||
|
|
||
| <div class=example> | ||
| The ''shape()'' function enables shapes that are responsive, rather than scalable. | ||
| While the ''polygon()'' shape is also responsive, it doesn't support curves. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great example!
polygon adds the
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, I'll update! |
||
|
|
||
| To demonstrate, let's start with a speech bubble, such as the following: | ||
|
|
||
| <img src="images/bubble.svg" width=300 style="background: unset"> | ||
|
|
||
| Using this shape with a ''clip-path'' can be done by using the ''path()'' function: | ||
|
|
||
| <pre highlight="css"> | ||
| .bubble { clip-path: path("m 5 0 H 95 Q 100 0 100 5 V 92 Q 100 97 95 97 H 70 l -2 3 l -2 -3 H 5 Q 0 97 0 92 V 5 Q 0 0 5 0") }; | ||
| </pre> | ||
|
|
||
| Altohugh this path can easily scale, the scaled results are not always desirable. e.g. when scaled to a small balloon, the arrow and corners are scaled to become almost invisible: | ||
|
|
||
| <img src="images/bubble.svg" width=100 style="background: unset"> | ||
|
|
||
| To construct this shape using the ''shape()'' function, let's start by turning all the pixel values from the ''path'' function to percentages. | ||
| Note that the ''shape()'' function begins with <css>from</css>: | ||
|
|
||
| <pre highlight="css"> | ||
| .bubble { clip-path: shape( from 5% 0%, | ||
| hline to 95%, | ||
| curve to 100% 5% with 100% 0%, | ||
| vline to 92%, | ||
| curve to 95% 97% with 100% 97%, | ||
| hline to 70%, | ||
| line by -2% 3%, | ||
| line by -2% -3%, | ||
| hline to 5%, | ||
| curve to 0% 92% with 0% 97%, | ||
| vline to 5%, | ||
| curve to 5% 0% with 0% 0%); } | ||
| </pre> | ||
|
|
||
| To make this path responsive, as in, respond well to size changes, we will convert some of its units to ''px'' values, | ||
| specifically the ones the control the curves and arrows: | ||
|
|
||
| <pre highlight="css"> | ||
| .bubble { clip-path: shape( from 5px 0%, | ||
| hline to calc(100% - 5px), | ||
| curve to 100% 5px with 100% 0%, | ||
| vline to calc(100% - 8px), | ||
| curve to calc(100% - 5px) calc(100% - 3px) with 100% calc(100% - 3px), | ||
| hline to 70%, | ||
| line by -2px 3px, | ||
| line by -2px -3px, | ||
| hline to 5px, | ||
| curve to 0% calc(100% - 8px) with 0% calc(100% - 3px), | ||
| vline to 5px, | ||
| curve to 5px 0% with 0% 0%); } | ||
| </pre> | ||
|
|
||
| When applied as ''clip-path'', it would looks like the following: | ||
| <p> | ||
| <img src="images/bubble-50.svg" width=150 style="background: unset"> | ||
| </p> | ||
|
|
||
| The whole speech bubble is scaled to the reference box, while the curves and arrows stay more constant. | ||
|
|
||
| Since ''shape()'' uses CSS units, we can replace some of the edges with ''position'' values: | ||
|
|
||
| <pre highlight="css"> | ||
| .bubble { clip-path: shape(from 5px 0, | ||
| hline to calc(100% - 5px), | ||
| curve to right 5px with right top, | ||
| vline to calc(100% - 8px), | ||
| curve to calc(100% - 5px) calc(100% - 3px) with right calc(100% - 3px), | ||
| hline to 70%, | ||
| line by -2px 3px, | ||
| line by -2px -3px, | ||
| hline to 5px, | ||
| curve to left calc(100% - 8px) with left calc(100% - 3px), | ||
| vline to 5px, | ||
| curve to 5px top with left top); } | ||
| </pre> | ||
|
|
||
| Another useful feature of ''shape()'' is that it can be used alongside CSS properties. In this case, | ||
| we can make the arrow and radius parametric, and even animate them: | ||
noamr marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| <pre highlight="css"> | ||
|
|
||
| @keyframes bubble { | ||
| from { | ||
| --radius: 30px; | ||
| --arrow-position: 20%; | ||
| } | ||
| } | ||
|
|
||
| :root { | ||
| --radius: 5px; | ||
| --arrow-length: 3px; | ||
| --arrow-half-width: 2px; | ||
| --arrow-position: 70%; | ||
| --arrow-bottom-offset: calc(100% - var(--radius) - var(--arrow-length)); | ||
| } | ||
|
|
||
| .bubble { | ||
| animation: bubble 100ms; | ||
| clip-path: shape(from var(---radius) top, | ||
| hline to calc(100% - var(---radius)), | ||
| curve to right var(---radius) with right top, | ||
| vline to var(---arrow-bottom-offset), | ||
| curve to calc(100% - var(---radius)) calc(100% - var(---arrow-length)) | ||
| with right calc(100% - var(---arrow-length)), | ||
| hline to var(---arrow-position), | ||
| line by var(---arrow-half-width) var(---arrow-length), | ||
| line by var(---arrow-half-width) calc(0px - var(---arrow-length)), | ||
| hline to var(---radius), | ||
| curve to left var(---arrow-bottom-offset) with left calc(100% - var(---arrow-length)), | ||
| vline to var(---radius), | ||
| curve to var(---radius) top with left top); } | ||
| </pre> | ||
|
|
||
|
|
||
|
|
||
| </div> | ||
|
|
||
| <h5 id=interpolating-shape> | ||
| Interpolating the ''shape()'' Function</h5> | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.