Renderowanie HTML jest oparte na modelu pudełkowym, ale życie (i projektowanie stron internetowych) to coś więcej niż prostokąty. CSS obsługuje wiele sposobów zmiany obszarów elementu, które są renderowane, co daje deweloperom swobodę tworzenia projektów obsługujących wszystkie kształty i rozmiary. Przycinanie umożliwia stosowanie kształtów geometrycznych, a maskowanie wpływa na widoczność na poziomie pikseli.
Ścieżki i kształty
CSS używa funkcji do definiowania kształtów. Ogólne informacje o funkcjach znajdziesz w module Funkcje CSS. W tej sekcji dowiesz się, jak tworzyć kształty w CSS. Wszystkie podane niżej przykłady korzystają z kształtów utworzonych za pomocą właściwości clip-path
, która ogranicza widoczny obszar tylko do tego, co znajduje się wewnątrz kształtu. Dzięki temu elementy mogą wizualnie różnić się od pola elementu. Więcej informacji o przycinaniu znajdziesz w dalszej części tego artykułu.
Kształty zdefiniowane w CSS mogą być kształtami podstawowymi (takimi jak koła, prostokąty i wielokąty) lub ścieżkami (które mogą definiować złożone i złożone kształty).
Kształty podstawowe
circle()
i ellipse()
Funkcje circle()
i ellipse()
definiują kształty okrągłe i owalne o promieniach względnych względem elementu. Funkcja circle()
przyjmuje jako argument pojedynczy rozmiar lub wartość procentową. Domyślnie obie funkcje pozycjonują kształt względem środka elementu. Oba akceptują opcjonalną pozycję po słowie kluczowym at
, którą można wyrazić jako długość, procent lub słowo kluczowe określające pozycję.
.my-element {
width: 60px;
height: 60px;
background: blue;
clip-path: circle(50%);
}
W przykładzie powyżej pokazano okrągłą ścieżkę przycinania utworzoną za pomocą funkcji circle()
. Pamiętaj, że promień 50%
tworzy okrąg o pełnej szerokości elementu. Funkcja ellipse()
przyjmuje 2 argumenty reprezentujące promienie poziomy i pionowy kształtu.
.my-element {
width: 60px;
height: 60px;
background: blue;
clip-path: ellipse(50% 25%);
}
W poprzednim przykładzie pokazano eliptyczną ścieżkę przycinania za pomocą funkcji ellipse()
. Pamiętaj, że promień 50% tworzy elipsę o pełnej szerokości elementu. Poniższy przykład przedstawia tę samą elipsę, której środek znajduje się u góry elementu.
.my-element {
width: 60px;
height: 60px;
background: blue;
clip-path: ellipse(50% 25% at center top);
}
rect()
i inset()
Funkcje rect()
i inset()
umożliwiają zdefiniowanie prostokąta na różne sposoby przez określenie położenia jego boków względem boków elementu. Dzięki temu możesz tworzyć prostokąty, które wizualnie różnią się od domyślnego pola elementu. Opcjonalnie akceptują słowo kluczowe round
, aby utworzyć prostokąt z zaokrąglonymi rogami, używając tej samej składni co właściwość skrócona border-radius
.
Funkcja rect()
określa położenie górnej i dolnej krawędzi prostokąta względem górnej krawędzi elementu oraz lewej i prawej krawędzi względem lewej krawędzi elementu. Ta funkcja przyjmuje 4 argumenty w jednostkach rozmiaru lub procentowych, które określają górną, prawą, dolną i lewą stronę. Funkcji rect()
możesz użyć, gdy chcesz utworzyć prostokąt, którego rozmiar nie zmienia się wraz ze zmianą rozmiaru elementu lub którego proporcje pozostają takie same, gdy zmienia się rozmiar elementu.
.my-element {
width: 80px;
height: 60px;
background: blue;
clip-path: rect(15px 75px 45px 10px);
}
W poprzednim przykładzie pokazano prostokątną ścieżkę przycinania zdefiniowaną za pomocą funkcji rect()
. Wymiary są podawane względem górnej i lewej krawędzi elementu, jak pokazano na diagramie.
Funkcja inset()
określa położenie boków prostokąta na podstawie odległości od każdego z boków elementu. Ta funkcja przyjmuje od 1 do 4 jednostek rozmiaru lub procentowych jako argumenty, co pozwala zdefiniować wiele boków naraz. Funkcji inset()
możesz użyć, gdy chcesz utworzyć prostokąt, który skaluje się wraz z elementem, lub prostokąt, który znajduje się w stałej odległości od krawędzi elementu.
.my-element {
width: 80px;
height: 60px;
background: blue;
clip-path: inset(15px 5px 15px 10px);
}
W poprzednim przykładzie pokazano prostokątną ścieżkę przycinania zdefiniowaną za pomocą funkcji inset()
. Wymiary są określane względem boków elementu.
Funkcje rect()
i inset()
opcjonalnie akceptują słowo kluczowe round
, aby utworzyć prostokąt z zaokrąglonymi rogami przy użyciu tej samej składni co właściwość skrócona border-radius
. Poniższy przykład przedstawia zaokrąglone wersje prostokątów pokazanych wcześniej.
.rounded-rect {
width: 80px;
height: 60px;
background: blue;
clip-path: inset(15px 5px 15px 10px round 5px);
}
.rounded-inset {
width: 80px;
height: 60px;
background: blue;
clip-path: inset(15px 5px 15px 10px round 5px);
}
polygon()
W przypadku innych kształtów, takich jak trójkąty, pięciokąty, gwiazdy itp., funkcja polygon()
umożliwia tworzenie kształtów przez łączenie wielu punktów liniami prostymi. Funkcja polygon()
akceptuje listę par składających się z 2 jednostek długości lub procentowych. Każda para opisuje punkt na wielokącie: pierwsza wartość to odległość od lewej krawędzi elementu, a druga – odległość od górnej krawędzi elementu. Nie musisz zamykać wielokąta, ponieważ zostanie on ukończony przez połączenie ostatniego punktu z pierwszym.
.my-element {
width: 60px;
height: 60px;
background: blue;
clip-path: polygon(
50% 0,
0 100%,
100% 100%
);
}
W poprzednim przykładzie utworzono trójkątną ścieżkę przycinania przez zdefiniowanie 3 punktów.
Domyślnie funkcja polygon()
renderuje obszary nakładające się jako wypełnione. Możesz zmienić to zachowanie za pomocą opcjonalnego pierwszego argumentu o nazwie reguła wypełniania. Aby przełączać się między obszarami wypełnionymi i niewypełnionymi, ustaw regułę wypełniania na evenodd
. Aby użyć domyślnej reguły wypełniania, ustaw ją na nonzero
.
W przykładzie powyżej pokazano funkcję polygon()
z funkcjami trygonometrycznymi, które służą do tworzenia wielokątów foremnych i gwiazd. Nie tworzy to największego możliwego wielokąta foremnego, który mieści się w elemencie, ani nie wyśrodkowuje go – pozostawimy to jako ćwiczenie do samodzielnego wykonania. Kształty gwiazd w tym przykładzie pokazują też reguły wypełniania nonzero
i evenodd
.
Złożone kształty
Gdy podstawowe funkcje kształtu nie wystarczają do opisania złożonego kształtu, CSS udostępnia funkcje, które używają bardziej zaawansowanej składni do opisywania cech takich jak krzywe i linie. Te funkcje są też przydatne w przypadku kształtów złożonych (składających się z wielu kształtów, np. koła z otworem).
path()
Funkcja path()
akceptuje ciąg znaków składni ścieżki SVG, aby opisać kształt. Umożliwia to tworzenie złożonych kształtów za pomocą instrukcji opisujących linie i krzywe, z których się składają. Bezpośrednie edytowanie składni SVG może być skomplikowane, dlatego zalecamy używanie specjalnego edytora wizualnego, który może eksportować składnię podczas tworzenia kształtów za pomocą funkcji path()
.
Funkcja path()
nie używa jednostek rozmiaru CSS, a wszystkie wartości są interpretowane jako piksele. Oznacza to, że kształty utworzone za pomocą funkcji ścieżki nie reagują na rozmiar elementu ani kontenera. Zalecamy używanie path()
tylko w przypadku kształtów o stałych wymiarach.
shape()
Funkcja shape()
używa składni poleceń do opisywania kształtu, podobnie jak funkcja path()
. Jednak polecenia funkcji shape()
są natywnym kodem CSS i mogą używać jednostek rozmiaru CSS. Umożliwia to zmianę rozmiaru kształtów zdefiniowanych za pomocą funkcji shape()
.
W powyższym przykładzie użyto funkcji path()
i shape()
do zdefiniowania kształtu serca i okręgu z otworem w środku. W przykładzie w przypadku obu funkcji użyto tej samej wartości w pikselach, ale funkcje shape()
mogły też używać innych jednostek rozmiaru CSS, takich jak procenty lub jednostki względne kontenera.
Obcinanie
Przycinanie określa, które obszary elementu są widoczne, podobnie jak przycinanie obrazu z magazynu. Właściwość clip-path
ustawia ścieżkę używaną do określania obszaru przycięcia.
Jak widać w przykładach z poprzedniej sekcji, dowolna z podstawowych funkcji kształtu lub ścieżki może być używana jako clip-path
. Właściwość clip-path
obsługuje też ścieżki zdefiniowane w elemencie SVG clipPath
, który może być osadzony lub znajdować się w osobnym pliku.
Na powyższym diagramie widać, jak dodanie atrybutu clip-path
do elementu obrazu zmienia widoczny obszar obrazu. Górna ścieżka przycinania korzysta z funkcji circle()
, a dolna z elementu SVG clipPath
. Pamiętaj, że okrąg utworzony za pomocą funkcji circle()
jest domyślnie wyśrodkowany na elemencie.
W przypadku właściwości clip-path
można podać tylko jedną ścieżkę. Aby przyciąć element za pomocą wielu kształtów, które się nie nakładają, użyj funkcji path()
lub shape()
, aby zdefiniować ścieżkę złożoną, albo użyj elementu SVG clipPath
. W bardziej złożonych przypadkach zamiast przycinania możesz użyć maskowania, o którym piszemy w dalszej części tego artykułu.
Przycinanie za pomocą kształtów
Aby przyciąć element za pomocą podstawowego kształtu lub funkcji ścieżki, ustaw właściwość clip-path
na wartość zwróconą przez funkcję, jak w poprzednich przykładach. Każda funkcja pozycjonuje kształt przycinania inaczej względem elementu, więc zapoznaj się z informacjami o poszczególnych funkcjach.
W powyższym przykładzie 2 elementy mają okrągły kształt clip-path
zastosowany za pomocą klasy .clipped
. Pamiętaj, że clip-path
jest umieszczony względem każdego elementu, a tekst w clip-path
nie jest dopasowywany do kształtu.
pole odniesienia ścieżki przycinania,
Domyślnie ścieżka przycinania elementu obejmuje jego obramowanie. Gdy używasz jednej z funkcji kształtu podstawowego, możesz ustawić pole odniesienia przycięcia tak, aby obejmowało tylko obszar elementu w obrębie obramowania. Prawidłowe wartości pola odniesienia to stroke-box
(wartość domyślna) i fill-box
(aby uwzględnić tylko obszar wewnątrz obramowania).
W przykładzie powyżej widać elementy z szerokim obramowaniem (20px
), z których każdy używa funkcji inset()
do ustawienia clip-path
. Element, który przycina względem obramowania elementu, nadal wyświetla część obramowania. Elementy, które są przycinane względem obszaru wewnątrz obramowania, nie mają obramowania i są mniejsze, nawet przy tej samej wartości wcięcia.
Przycinanie za pomocą grafiki
Ścieżka przycinania może być zdefiniowana w dokumencie SVG, osadzonym w dokumencie HTML lub do którego odwołanie jest zewnętrzne. Może to być przydatne do definiowania złożonych ścieżek przycinania utworzonych w programach graficznych lub ścieżek przycinania, które łączą wiele kształtów.
<img id="kitten" src="kitten.png">
<svg>
<defs>
<clipPath id="kitten-clip-shape">
<circle cx="130" cy="175" r="100" />
</clipPath>
</defs>
</svg>
<style>
#kitten {
clip-path: url(#kitten-clip-shape);
}
</style>
W poprzednim przykładzie element clipPath
z atrybutem id
o wartości kitten-clip-shape
jest stosowany do elementu <img>
. W tym przypadku dokument SVG jest umieszczony w kodzie HTML. Jeśli dokument SVG jest plikiem zewnętrznym o nazwie kitten-clipper.svg
, element clipPath
będzie odwoływać się do url(kitten-clipper.svg#kitten-clip-shape)
.
Zamaskowanie
Maskowanie to kolejna metoda określania, które obszary elementu mają być widoczne lub ukryte. Przycinanie wykorzystuje podstawowe kształty lub ścieżki, a maskowanie – piksele z obrazu lub gradientu, aby określić widoczność. W przeciwieństwie do przycinania maskowanie umożliwia częściową przezroczystość obszarów elementu. Do elementu można zastosować wiele obrazów maski, aby uzyskać różne efekty.
Aby zastosować maskę, ustaw właściwość mask-image
. Ta właściwość akceptuje co najmniej 1 obraz, gradient lub odwołanie do elementów <mask>
w dokumencie SVG. Możesz zastosować wiele obrazów maski, oddzielając je przecinkami.
.my-element {
mask-image: url(my-mask.png),
linear-gradient(black 0%, transparent 100%);
}
W powyższym przykładzie element .my-element
jest maskowany za pomocą obrazu PNG, a następnie gradientu liniowego. Domyślnie wiele masek jest dodawanych do siebie, aby utworzyć maskę końcową.
W przykładzie powyżej widać obraz z co najmniej jedną zastosowaną maską. Przełączaj poszczególne maski, aby zobaczyć, jak się sumują i tworzą efekt końcowy.
Maskowanie alfa a maskowanie luminancją
Maskę możesz zastosować, używając alpha
lub luminance
obrazu. Podczas maskowania na podstawie elementu alpha
do elementu stosowana jest przezroczystość każdego piksela na obrazie maski, z pominięciem informacji o kolorze tego piksela. Podczas maskowania na podstawie luminance
do elementu stosowana jest zarówno przezroczystość, jak i wartość każdego piksela (jasność lub ciemność). Maskowanie według luminancji traktuje jaśniejsze kolory jako widoczne, a ciemniejsze jako niewidoczne.
Aby ustawić tryb maskowania, użyj właściwości mask-mode
. Domyślnie właściwość mask-mode
ma wartość match-source
, która ustawia tryb na podstawie typu obrazu maski. W przypadku obrazów i gradientów domyślnie będzie to alpha
. W przypadku masek SVG domyślną wartością będzie wartość właściwości mask-type
elementu <mask>
lub luminance
, jeśli nie zdefiniowano właściwości mask-type
.
W powyższym przykładzie jako maski użyto wzorca testowego pokazującego różne wartości koloru i alfa. Przełączając mask-mode
, możesz zobaczyć, że tryb alpha
opiera się na przejrzystości, a tryb luminance
– na jasności koloru i przejrzystości.
Dodatkowe właściwości maskowania
CSS udostępnia dodatkowe właściwości, które pozwalają precyzyjnie dostosować działanie masek. Każda z tych właściwości akceptuje rozdzieloną przecinkami listę wartości, które będą dopasowywane do listy masek ustawionej przez właściwość mask-image
. Jeśli wartości jest mniej niż masek, lista będzie powtarzana, dopóki dla każdej maski nie zostanie ustawiona wartość. Jeśli wartości jest więcej niż masek, nadmiarowe wartości są odrzucane.
Właściwość | Opis |
---|---|
mask-clip |
Określa, do którego pola odniesienia elementu mają być stosowane maski. Domyślna wartość to |
mask-composite |
Określa interakcję między maskami, gdy do tego samego elementu zastosowano kilka masek. Domyślna wartość to |
mask-origin |
Ustawia pole odniesienia, które służy jako punkt początkowy maski. Domyślna wartość to |
mask-position |
Ustawia pozycję maski względem elementu |
mask-repeat |
Określa, jak maska jest powtarzana, jeśli element zamaskowany jest większy od maski. Domyślna wartość to |
mask-size |
Określa, jak maska zmienia rozmiar względem rozmiaru maskowanego elementu. Domyślna wartość to |
Skrót maski
Za pomocą skrótu maski możesz ustawić jednocześnie wiele właściwości maski. Może to uprościć ustawianie wielu masek, ponieważ wszystkie właściwości każdej maski są zgrupowane. Skrót maski jest równoważny ustawieniu tych właściwości w kolejności: mask-image
, mask-mode
, mask-position
, mask-size
, mask-repeat
, mask-origin
, mask-clip
i mask-composite
. Nie musisz uwzględniać wszystkich właściwości. Te, które nie zostaną uwzględnione, zostaną zresetowane do wartości początkowej. Każda maska może obsługiwać do 8 właściwości, dlatego warto mieć dostęp do pełnej dokumentacji.
.longhand {
mask-image: linear-gradient(white, black),
linear-gradient(90deg, black, transparent);
mask-mode: luminance, alpha;
mask-position: bottom left, top right;
mask-size: 50% 50%, 30% 30%;
}
.shorthand {
mask: linear-gradient(white, black) luminance bottom left / 50% 50%,
linear-gradient(90deg, black, transparent) alpha top right / 30% 30%;
}
W powyższym przykładzie do każdej klasy zastosowano 2 maski. Pierwszy przykład używa poszczególnych właściwości, a drugi – skrótu mask
. Oba style są równoważne.
Tekst ciągły wokół elementów pływających
Przycinając lub maskując element, zmieniasz tylko widoczny obszar w jego polu, ale samo pole pozostaje bez zmian. Oznacza to, że element pływający będzie wpływać na przepływ dokumentu na podstawie oryginalnego pola ograniczającego, a nie widocznych części elementu. Aby zdefiniować przepływ wokół elementu, użyj właściwości shape-outside
wraz ze ścieżką przycinania.
Właściwość shape-outside
określa kształt, wokół którego będzie przepływać treść elementu. Może to być dowolna z podstawowych funkcji kształtu, ale nie kształty zdefiniowane za pomocą funkcji path()
lub shape()
ani clipPath
zdefiniowany w dokumencie SVG.
Właściwość shape-outside
akceptuje też obraz lub gradient. Podobnie jak w przypadku maskowania, granice kształtu będą zależeć od przezroczystości obrazu lub gradientu. Właściwość shape-image-threshold
określa, które poziomy przezroczystości są uwzględniane w kształcie.
Kształty w animacji
Animowanie przycinania
Możesz animować właściwość clip-path
, płynnie przechodząc od jednego kształtu do drugiego. Aby uzyskać płynne animacje, musisz używać tej samej funkcji kształtu dla każdej klatki kluczowej. Podczas korzystania z funkcji polygon()
lub shape()
w każdej klatce kluczowej musi być użyta ta sama liczba punktów.
W powyższym przykładzie clip-path
elementu zmienia się z pięciokąta na gwiazdę zdefiniowaną za pomocą funkcji polygon()
. W przykładzie użyto reguły wypełniania evenodd
, aby pokazać, jak animowane punkty tworzą obszary nakładające się na siebie.
Animowanie za pomocą ścieżki przesunięcia
Możesz też animować elementy wzdłuż ścieżek utworzonych za pomocą tych funkcji kształtu. Właściwość offset-path
określa kształt, który ma być używany jako ścieżka, a właściwość offset-distance
określa pozycję wzdłuż tej ścieżki. Możesz też użyć funkcji ray()
z właściwością offset-path
, aby animować wzdłuż linii prostej.
W przykładzie powyżej pokazano, jak używać tego samego wielokąta zarówno w przypadku clip-path
, jak i offset-path
. Animacja wykorzystuje offset-distance
do przesuwania mniejszych gwiazd wzdłuż tego samego wielokąta, którego duża gwiazda używa jako clip-path
.
Sprawdź swoją wiedzę
Które z poniższych funkcji kształtu są prawidłowe?
circle()
square()
hexagon()
polygon()
rectangle()
inset()
Prawda czy fałsz: kształty zdefiniowane za pomocą funkcji path()
można określać za pomocą wartości procentowych.
Prawda czy fałsz: ustawienie ścieżki przycinania elementu nie zmieni przepływu tekstu wokół niego.
Które z tych elementów mogą być użyte jako ścieżka przycinania?
clipMask
Które z tych elementów można wykorzystać jako maskę?
circle()
lub rect()
;