Fantazyjne dekoracje obrazu: Single Element Magic PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Fantazyjne dekoracje obrazu: Magia pojedynczego elementu

Jak mówi tytuł, zamierzamy ozdobić obrazy! Istnieje wiele innych artykułów, które o tym mówią, ale to, co tutaj omawiamy, jest nieco inne, ponieważ jest to większe wyzwanie. Wyzwanie? Udekoruj obraz, używając tylko tag i nic więcej.

To prawda, bez dodatkowych znaczników, bez divów i bez pseudo-elementów. Tylko jeden tag.

Brzmi trudno, prawda? Ale pod koniec tego artykułu – i innych, które składają się na tę małą serię – udowodnię, że CSS jest wystarczająco potężny, aby dać nam wspaniałe i oszałamiające wyniki pomimo ograniczeń pracy z jednym elementem.

Seria Fancy Image Decoration

  • Magia pojedynczego elementu — jesteś tutaj
  • Maski i zaawansowane efekty najechania (nadchodzi 21 października )
  • Kontury i złożone animacje (nadchodzi 28 października )

Zacznijmy od naszego pierwszego przykładu

Zanim zagłębimy się w kod, wymieńmy możliwości stylizacji i bez dodatkowych elementów lub pseudoelementów. Możemy użyć border, box-shadow, outlineI, oczywiście, background. Dodanie tła do obrazu może wyglądać dziwnie, ponieważ nie możemy go zobaczyć, ponieważ będzie za obrazem — ale sztuczka polega na tym, aby stworzyć przestrzeń na około obraz za pomocą padding i / lub border a następnie narysuj nasze tło w tej przestrzeni.

Myślę, że wiesz, co będzie dalej, odkąd opowiedziałem background, prawo? TAk, gradienty! Wszystkie dekoracje, które zamierzamy wykonać, opierają się na wielu gradientach. Jeśli masz śledził mnie przez chwilę myślę, że to prawdopodobnie nie jest dla ciebie zaskoczeniem.

Wróćmy do naszego pierwszego przykładu:

img {
  --s: 10px; /* control the size */
  padding: var(--s);
  border: calc(2 * var(--s)) solid #0000;
  outline: 1px solid #000;
  outline-offset: calc(-1 * var(--s));
  background: conic-gradient(from 90deg at 1px 1px, #0000 25%, #000 0);
}

Definiujemy padding i przezroczysty border za pomocą zmiennej --s stworzyć przestrzeń wokół naszego obrazu równą trzykrotności tej zmiennej.

Dlaczego używamy obu? padding i border zamiast jednego czy drugiego? Możemy uzyskać używając tylko jednego z nich, ale potrzebuję tej kombinacji do mojego gradientu, ponieważ domyślnie wartość początkowa background-clip is border-box i background-origin jest równe padding-box.

Oto ilustracja krok po kroku, aby zrozumieć logikę:

Początkowo nie mamy żadnych granic na obrazie, więc nasz gradient utworzy dwa segmenty z 1px grubości. (Ja używam 3px w tym konkretnym demo, aby było łatwiej zobaczyć.) Dodajemy kolorową ramkę, a gradient nadal daje nam ten sam wynik w obszarze dopełnienia (ze względu na background-origin), ale powtarza się za granicą. Jeśli sprawimy, że kolor obramowania będzie przezroczysty, możemy użyć powtórzenia i otrzymamy żądaną ramkę.

Połączenia outline w demie ma ujemny offset. To tworzy kwadratowy kształt u góry gradientu. Otóż ​​to! Dodaliśmy ładną dekorację do naszego obrazu za pomocą jednego gradientu i outline. Mogliśmy użyć więcej gradientów! Ale zawsze staram się, aby mój kod był jak najprostszy i stwierdziłem, że dodanie outline tak jest lepiej.

Oto rozwiązanie gradientowe, w którym używam tylko padding zdefiniować przestrzeń. Nadal ten sam wynik, ale z bardziej złożoną składnią.

Wypróbujmy inny pomysł:

W tym przypadku wziąłem poprzedni przykład usunąłem outlinei zastosował a clip-path wyciąć gradient z każdej strony. The clip-path value jest nieco gadatliwa i myląca, ale oto ilustracja, aby lepiej zobaczyć jej punkty:

Fantazyjne dekoracje obrazu: Magia pojedynczego elementu

Myślę, że rozumiesz główną ideę. Połączymy tła, kontury, przycinanie i trochę maskowania, aby uzyskać różne rodzaje dekoracji. Zamierzamy również rozważyć kilka fajnych animacji najechania kursorem jako dodatkowy bonus! To, na co patrzyliśmy do tej pory, to tylko mały przegląd tego, co nadchodzi!

Rama tylko narożna

Ten zajmuje cztery gradienty. Każdy gradient obejmuje jeden róg, a po najechaniu myszą je rozszerzamy, aby utworzyć pełną klatkę wokół obrazu. Przeanalizujmy kod jednego z gradientów:

--b: 5px; /* border thickness */
background: conic-gradient(from 90deg at top var(--b) left var(--b), #0000 90deg, darkblue 0) 0 0;
background-size: 50px 50px; 
background-repeat: no-repeat;

Narysujemy gradient o rozmiarze równym 50px 50px i umieść go w lewym górnym rogu (0 0). Jeśli chodzi o konfigurację gradientu, oto ilustracja krok po kroku pokazująca, jak osiągnąłem ten wynik.

Mamy tendencję do myślenia, że ​​gradienty są dobre tylko do przejścia między dwoma kolorami. Ale w rzeczywistości możemy z nimi zrobić o wiele więcej! Są szczególnie przydatne przy tworzeniu różnych kształtów. Sztuką jest upewnienie się, że mamy twarde zatrzymania między kolorami — jak w powyższym przykładzie — zamiast płynnych przejść:

#0000 25%, darkblue 0

To w zasadzie mówi: „wypełnij gradient przezroczystym kolorem, aż 25% obszaru, a następnie wypełnij pozostały obszar darkblue.

Możesz drapać się po głowie 0 wartość. To trochę hack, aby uprościć składnię. W rzeczywistości powinniśmy to wykorzystać, aby mocno zatrzymać się między kolorami:

#0000 25%, darkblue 25%

To jest bardziej logiczne! Przezroczysty kolor kończy się na 25% i darkblue zaczyna się dokładnie tam, gdzie kończy się przezroczystość, zatrzymując się. Jeśli zamienimy drugi na 0, przeglądarka zrobi to za nas, więc jest to nieco bardziej wydajny sposób.

Gdzieś w Specyfikacja, to mówi:

Jeśli kolor stop or wskazówka przejścia ma pozycję, która jest mniejsza niż określona pozycja dowolnego zakończenia koloru lub wskazówki przejścia przed nim na liście, ustaw jego pozycję na równą największej określonej pozycji dowolnego zakończenia koloru lub wskazówki przejścia przed nim.

0 jest zawsze mniejsza niż jakakolwiek inna wartość, więc przeglądarka zawsze konwertuje ją na największą wartość, która występuje przed nią w deklaracji. W naszym przypadku ta liczba to 25%.

Teraz stosujemy tę samą logikę do wszystkich narożników i kończymy następującym kodem:

img {
  --b: 5px; /* border thickness */
  --c: #0000 90deg, darkblue 0; /* define the color here */
  padding: 10px;
  background:
    conic-gradient(from 90deg  at top    var(--b) left  var(--b), var(--c)) 0 0,
    conic-gradient(from 180deg at top    var(--b) right var(--b), var(--c)) 100% 0,
    conic-gradient(from 0deg   at bottom var(--b) left  var(--b), var(--c)) 0 100%,
    conic-gradient(from -90deg at bottom var(--b) right var(--b), var(--c)) 100% 100%;
  background-size: 50px 50px; /* adjust border length here */
  background-repeat: no-repeat;
}

Wprowadziłem zmienne CSS, aby uniknąć pewnej redundancji, ponieważ wszystkie gradienty używają tej samej konfiguracji kolorów.

Aby uzyskać efekt najechania, wszystko, co robię, to zwiększanie rozmiaru gradientów, aby utworzyć pełną klatkę:

img:hover {
  background-size: 51% 51%;
}

Tak to jest 51% zamiast 50% — który tworzy niewielkie nakładanie się i pozwala uniknąć ewentualnych luk.

Wypróbujmy inny pomysł przy użyciu tej samej techniki:

Tym razem używamy tylko dwóch gradientów, ale z bardziej złożoną animacją. Najpierw aktualizujemy położenie każdego gradientu, a następnie zwiększamy jego rozmiary, aby utworzyć pełną klatkę. Wprowadziłem też więcej zmiennych dla lepszej kontroli nad kolorem, rozmiarem, grubością, a nawet odstępem między obrazem a ramką.

img {
  --b: 8px;  /* border thickness*/
  --s: 60px; /* size of the corner*/
  --g: 14px; /* the gap*/
  --c: #EDC951; 

  padding: calc(var(--b) + var(--g));
  background-image:
    conic-gradient(from  90deg at top    var(--b) left  var(--b), #0000 25%, var(--c) 0),
    conic-gradient(from -90deg at bottom var(--b) right var(--b), #0000 25%, var(--c) 0);
  background-position:
    var(--_p, 0%) var(--_p, 0%),
    calc(100% - var(--_p, 0%)) calc(100% - var(--_p, 0%));
  background-size: var(--s) var(--s);
  background-repeat: no-repeat;
  transition: 
    background-position .3s var(--_i,.3s), 
    background-size .3s calc(.3s - var(--_i, .3s));
}
img:hover {
  background-size: calc(100% - var(--g)) calc(100% - var(--g));
  --_p: calc(var(--g) / 2);
  --_i: 0s;
}

Dlaczego --_i i --_p zmienne mają w nazwie podkreślenie? Podkreślenia są częścią konwencji nazewnictwa, której używam do rozważenia „wewnętrznych” zmiennych używanych do optymalizacji kodu. Nie są niczym specjalnym, ale chcę zrobić różnicę między zmiennymi, które dostosowujemy, aby kontrolować klatkę (np. --b, --c, itp.) i tych, których używam do skrócenia kodu.

Kod może wyglądać na mylący i niełatwy do uchwycenia, ale napisałem: seria trzyczęściowa gdzie opisuję taką technikę. Gorąco polecam przeczytanie przynajmniej pierwszego artykułu, aby zrozumieć, w jaki sposób dotarłem do powyższego kodu.

Oto ilustracja, aby lepiej zrozumieć różne wartości:

Trzykrotne pokazanie tego samego obrazu dwóch klasycznych samochodów w celu zilustrowania zmiennych CSS użytych w kodzie.
Fantazyjne dekoracje obrazu: Magia pojedynczego elementu

Ujawnienie ramki

Wypróbujmy inny rodzaj animacji, w którym po najechaniu kursorem wyświetlamy pełną klatkę:

Fajnie, prawda? A ty, jeśli przyjrzysz się uważnie, zauważysz, że linie znikają w przeciwnym kierunku po wygaszeniu myszy, co sprawia, że ​​efekt jest jeszcze bardziej fantazyjny! Podobny efekt zastosowałem w poprzedni artykuł.

Ale tym razem, zamiast obejmować cały element, pokrywam tylko niewielką część, definiując a height dostać coś takiego:

To jest górna granica naszej ramy. Powtarzamy ten sam proces po każdej stronie obrazu i uzyskujemy efekt najechania:

img {
  --b: 10px; /* the border thickness*/
  --g: 5px; /* the gap on hover */
  --c: #8A9B0F; 

  padding: calc(var(--g) + var(--b));
  --_g: no-repeat linear-gradient(var(--c) 0 0);
  background: 
    var(--_g) var(--_i, 0%) 0,
    var(--_g) 100% var(--_i, 0%),
    var(--_g) calc(100% - var(--_i, 0%)) 100%,
    var(--_g) 0 calc(100% - var(--_i, 0%));
  background-size: var(--_i, 0%) var(--b),var(--b) var(--_i, 0%);
  transition: .4s, background-position 0s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
}

Jak widać, stosuję ten sam gradient cztery razy i każdy ma inną pozycję, aby pokryć tylko jedną stronę na raz.

Inny? Chodźmy!

Ten wygląda trochę zawile i rzeczywiście wymaga trochę wyobraźni, aby zrozumieć, jak dwa stożkowe gradienty wywołują tego rodzaju magię. Oto demo ilustrujące jeden z gradientów:

Pseudoelement symuluje gradient. Początkowo jest poza zasięgiem wzroku, a po najechaniu na nią najpierw zmieniamy jego pozycję, aby uzyskać górną krawędź kadru. Następnie zwiększamy wysokość, aby uzyskać prawą krawędź. Kształt gradientu jest podobny do tego, którego używaliśmy w poprzedniej sekcji: dwa segmenty, aby pokryć dwie strony.

Ale dlaczego zrobiłem szerokość gradientu? 200%? Pomyślałbyś 100% wystarczy, prawda?

100% powinno wystarczyć, ale nie będę mógł przesunąć gradientu tak, jak chcę, jeśli zachowam jego szerokość równą 100%. To kolejne małe dziwactwo związane z tym, jak background-position Pracuje. Omówię to w poprzedni artykuł. ja również opublikował odpowiedź na Stack Overflow radzenia sobie z tym. Wiem, że to dużo czytania, ale naprawdę warto poświęcić na to czas.

Teraz, gdy wyjaśniliśmy logikę jednego gradientu, drugi jest łatwy, ponieważ robi dokładnie to samo, ale zakrywa lewą i dolną krawędź. Wystarczy zamienić kilka wartości i gotowe:

img {
  --c: #8A9B0F; /* the border color */
  --b: 10px; /* the border thickness*/
  --g: 5px;  /* the gap */

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, var(--c) 0;
  background: 
    conic-gradient(from 180deg at top    var(--b) right var(--b), var(--_g))
     var(--_i, 200%) 0 / 200% var(--_i, var(--b))  no-repeat,
    conic-gradient(            at bottom var(--b) left  var(--b), var(--_g))
     0 var(--_i, 200%) / var(--_i, var(--b)) 200%  no-repeat;
  transition: .3s, background-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, background-size .3s .3s;
}

Jak widać, oba gradienty są prawie identyczne. Po prostu zamieniam wartości rozmiaru i pozycji.

Obrót ramy

Tym razem nie zamierzamy obrysowywać naszego obrazu ramką, a raczej dopasowujemy wygląd już istniejącego.

Zapewne pytasz, jak do cholery jestem w stanie przekształcić linię prostą w linię pod kątem. Nie, magia jest inna. To tylko iluzja, którą uzyskujemy po połączeniu prostych animacji dla czterech gradientów.

Zobaczmy, jak powstaje animacja dla górnego gradientu:

Po prostu aktualizuję pozycję powtarzającego się gradientu. Jeszcze nic nadzwyczajnego! Zróbmy to samo dla prawej strony:

Czy zaczynasz dostrzegać sztuczkę? Oba gradienty przecinają się w rogu, tworząc iluzję, w której linia prosta zmienia się na ukośną. Usuńmy kontur i ukryjmy przepełnienie, aby lepiej go zobaczyć:

Teraz dodajemy jeszcze dwa gradienty, aby pokryć pozostałe krawędzie i gotowe:

img {
  --g: 4px; /* the gap */
  --b: 12px; /* border thickness*/
  --c: #669706; /* the color */

  padding: calc(var(--g) + var(--b));
  --_c: #0000 0 25%, var(--c) 0 50%;
  --_g1: repeating-linear-gradient(90deg ,var(--_c)) repeat-x;
  --_g2: repeating-linear-gradient(180deg,var(--_c)) repeat-y;
  background:
    var(--_g1) var(--_p, 25%) 0, 
    var(--_g2) 0 var(--_p, 125%),
    var(--_g1) var(--_p, 125%) 100%, 
    var(--_g2) 100% var(--_p, 25%);
  background-size: 200% var(--b), var(--b) 200%;
  transition: .3s;
}
img:hover {
  --_p: 75%;
}

Jeśli weźmiemy ten kod i nieco go dostosujemy, otrzymamy kolejną fajną animację:

Czy potrafisz zrozumieć logikę w tym przykładzie? To twoja praca domowa! Kod może wyglądać przerażająco, ale używa tej samej logiki, co poprzednie przykłady, które przyjrzeliśmy się. Spróbuj wyizolować każdy gradient i wyobraź sobie, jak się animuje.

Zamykając

To dużo gradientów w jednym artykule!

Na pewno jest i ostrzegałem cię! Ale jeśli wyzwaniem jest udekorowanie obrazu bez dodatkowych elementów i pseudoelementów, pozostaje nam tylko kilka możliwości, a gradienty są najpotężniejszą opcją.

Nie martw się, jeśli zagubisz się w niektórych wyjaśnieniach. Zawsze polecam niektóre z moich starych artykułów, w których szczegółowo omawiam niektóre koncepcje, które wykorzystaliśmy do tego wyzwania.

Wyjdę z ostatnim demo, które zatrzyma cię do następnego artykułu z tej serii. Tym razem używam radial-gradient() aby stworzyć kolejny zabawny efekt najechania. Pozwolę ci przeanalizować kod, aby dowiedzieć się, jak to działa. Zadaj mi pytania w komentarzach, jeśli utkniesz!

Seria Fancy Image Decoration

  • Magia pojedynczego elementu — jesteś tutaj
  • Maski i zaawansowane efekty najechania (nadchodzi 21 października )
  • Kontury i złożone animacje (nadchodzi 28 października )

Znak czasu:

Więcej z Sztuczki CSS