Sposoby animowania obramowania za pomocą CSS
Ustawianie obramowania
Dostępnych jest kilka metod ustawiania obramowania elementu: border
, outline
i box-shadow
. Jak szczegółowo opisano w artykule 3 metody dodawania obramowania elementów za pomocą arkusza CSS Stephanie Eckles, każda metoda ma swoje zalety i wady, zwłaszcza jeśli chodzi o animowanie obramowania. Głównym powodem, dla którego nie warto używać prawidłowego pliku CSS border
, są animacje.
Ostatnio zwrócił moją uwagę artykuł Fantastic CSS border animation (Fantastyczna animacja obramowania w CSS), w którym autorka Coco przedstawiła więcej opcji. Wstrzykując treści wygenerowane za pomocą funkcji ::before
i ::after
, tworzą fałszywą ramkę, która jest następnie animowana.
Najbardziej rzucają mi się w oczy animowane wizualizacje użyte w artykule. Dobrze wyjaśniają, co dokładnie jest robione, aby osiągnąć pożądany efekt.
Zarówno biała warstwa, jak i kolorowe linie są treściami wygenerowanymi. Dzięki temu, że biała warstwa pojawia się i znika, widać, jak elementy się nakładają i jak działa animacja.
Zachowanie modelu pudełka
Wadą korzystania z treści wygenerowanych do naśladowania obramowania jest to, że w efekcie uzyskuje się uszkodzony model pudełka: treści mogą zasłaniać fałszywe obramowanie, ponieważ jest ono namalowane pod spodem. Aby to obejść, musisz zastosować odpowiednią wartość border-width
jako padding
.
Aby uzyskać prawdziwą ramkę i utrzymać działanie modelu pudełka, możesz użyć kilku teł, które następnie rozciągniesz w obszarze ramki.
Podstawy
Zacznijmy od utworzenia kropkowanej ramki i dodania kilku tła.
/* Size of the border */
--border-size: 0.5rem;
/* Create a dotted border */
border: var(--border-size) dotted lime;
/* Create two background layers:
1. A white semi-transparent
2. A layer with the colored boxes
*/
background-image:
linear-gradient(to right, rgb(255 255 255 / 0.5), rgb(255 255 255 / 0.5)),
conic-gradient(
from 45deg,
#d53e33 0deg 90deg,
#fbb300 90deg 180deg,
#377af5 180deg 270deg,
#399953 270deg 360deg
)
;
Rozmiar tła z background-origin
Jak widzisz, z tłem dzieje się coś dziwnego: jest ono namalowane na krawędzi, ale conic-gradient
wygląda na nieprawidłowe. Jest to zamierzone działanie: domyślnie obrazy tła nie są rysowane w ramce, ponieważ ich punktem wyjścia jest padding-box
elementu. Aby jednak utworzyć obramowanie, obrazy tła są powtarzane w ramce, co powoduje dziwny efekt wizualny.
Aby rozwiązać ten problem, musisz rozciągnąć tło, tak aby zajmowało też obszar obramowania. Możesz to zrobić ręcznie, rozciągając i przesuwając tło, ale najlepiej użyć właściwości background-origin
, aby dopasować rozmiar tła do border-box
.
/* Manually add or offset the size of the border where needed */
background-position: calc(var(--border-size) * -1) calc(var(--border-size) * -1);
background-size: calc(var(--border-size) * 2 + 100%) calc(var(--border-size) * 2 + 100%);
background-origin: border-box;
Ten jeden element znacznie poprawia wygląd:
Zmniejsz białą warstwę tła o wartość background-clip
Tło ma teraz zajmować całą przestrzeń, więc półprzezroczystą warstwę trzeba ponownie zmniejszyć. Zamiast ponownie stosować parametr background-size
, możesz użyć parametru background-clip
i ustawić go na padding-box
. Dzięki temu tło nie będzie już widoczne pod obszarem obramowania.
background-clip:
padding-box, /* Clip white semi-transparent to the padding-box */
border-box /* Clip colored boxes to the border-box (default) */
;
Na koniec ustaw obramowanie na transparent
, aby uzyskać pełny efekt.
border: 0.3rem dotted transparent;
Animacja
Aby przywrócić animację obramowania, możesz zmienić kąt początkowy conic-gradient
.
--angle: 0deg;
conic-gradient(
from var(--angle),
#d53e33 0deg 90deg,
#fbb300 90deg 180deg,
#377af5 180deg 270deg,
#399953 270deg 360deg
);
Dzięki funkcji @property jest to bardzo proste w przeglądarkach, które ją obsługują:
@property --angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
@keyframes rotate {
to {
--angle: 360deg;
}
}
Po połączeniu kod wygląda tak:
Treści dodatkowe: border-image
Jak już wcześniej wspomnieliśmy, aby narysować gradientową ramkę, możesz użyć atrybutu CSS border-image
.
Pozwala to na uproszczenie kodu, ponieważ nie musisz zajmować się nakładającymi się tłami. Animację można zastosować w taki sam sposób jak wcześniej.
/* Create a border */
border: 0.5rem solid transparent;
/* Paint an image in the border */
border-image:
conic-gradient(
from var(--angle),
#d53e33 0deg 90deg,
#fbb300 90deg 180deg,
#377af5 180deg 270deg,
#399953 270deg 360deg
) 1
;
Jednak w przypadku tego podejścia kilka rzeczy nie działa:
- Format
border-image
nie jest zależny od formatuborder-radius
; zawsze będzie prostokątny. - Gdy ustawisz wypełnienie
border-image-slice
,border-image
nie zostanie namalowany pod ustawieniembackground
, ale nad nim. Może to być kłopotliwe, jeśli chcesz, aby tło było półprzezroczyste.
W podsumowaniu
W CSS istnieje wiele możliwości animowania obramowania. W zależności od przypadku użycia możesz skorzystać z jednego lub drugiego.