Вигадливі декорації зображень: маски та вдосконалені ефекти наведення PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.

Вигадливі прикраси зображень: маски та розширені ефекти наведення

Ласкаво просимо до частини 2 цієї серії з трьох частин! Ми все ще декоруємо зображення без зайвих елементів і псевдоелементів. Сподіваюся, ви вже знайшли час, щоб переварити Частина 1 оскільки ми продовжуватимемо працювати з великою кількістю градієнтів, щоб створити чудові візуальні ефекти. Ми також збираємося представити CSS mask властивість для більш складних декорацій і ефектів наведення.

Серія Fancy Image Decorations

  • Магія одного елемента
  • Маски та розширені ефекти наведення (ти тут!)
  • Контури та складні анімації (наступає 28 жовтня )

Давайте повернемося до першого прикладу, над яким ми разом працюємо…

Поштова марка

Вірте чи ні, але для створення CSS-ефекту поштової марки потрібні два градієнти та фільтр:

img {
  --r: 10px; /* control the radius of the circles */
  padding: calc(2 * var(--r));
  filter: grayscale(.4);
  background: 
    radial-gradient(var(--r),#0000 98%,#fff) round
      calc(-1.5 * var(--r)) calc(-1.5 * var(--r)) / calc(3 * var(--r)) calc(3 * var(--r)),
    linear-gradient(#fff 0 0) no-repeat
      50% / calc(100% - 3 * var(--r)) calc(100% - 3 * var(--r));
}

Як ми бачили в попередня стаття, першим кроком є ​​звільнення місця навколо зображення за допомогою padding щоб ми могли намалювати фоновий градієнт і побачити його там. Тоді ми використовуємо комбінацію radial-gradient() та linear-gradient() щоб вирізати ці кола навколо зображення.

Ось покрокова ілюстрація, яка показує, як налаштовані градієнти:

Зверніть увагу на використання round значення на другому кроці. Це дуже важливо для трюку, оскільки забезпечує ідеальне вирівнювання розміру градієнта з усіх боків, незалежно від ширини чи висоти зображення.

Від специфікація: Зображення повторюється так часто, як це поміщається в області позиціонування фону. Якщо воно не вміщується цілу кількість разів, воно змінюється, щоб воно вміщалося.

Округла рамка

Давайте подивимося на іншу прикрасу зображення, яка використовує кола…

У цьому прикладі також використовується a radial-gradient(), але цього разу я створив кола навколо зображення замість ефекту вирізання. Зауважте, що я також використовую round значення знову. Найскладніша частина тут — це прозорий проміжок між рамкою та зображенням, де я тягнуся до CSS mask майно:

img {
  --s: 20px; /* size of the frame */
  --g: 10px; /* the gap */
  --c: #FA6900; 

  padding: calc(var(--g) + var(--s));
  background: 
    radial-gradient(farthest-side, var(--c) 97%, #0000) 
      0 0 / calc(2 * var(--s)) calc(2 * var(--s)) round;
  mask:
    conic-gradient(from 90deg at calc(2 * var(--s)) calc(2 * var(--s)), #0000 25%, #000 0)
      calc(-1 * var(--s)) calc(-1 * var(--s)),
    linear-gradient(#000 0 0) content-box;
}

Маскування дозволяє нам показати область зображення — завдяки linear-gradient() там — а також 20px навколо кожного боку від нього — завдяки conic-gradient(), 20px є не що інше, як змінна --s що визначає розмір кадру. Іншими словами, нам потрібно приховати розрив.

Ось що я маю на увазі:

Лінійний градієнт — це синя частина фону, а конічний градієнт — червона частина фону. Цю прозору частину між обома градієнтами ми вирізаємо з нашого елемента, щоб створити ілюзію внутрішньої прозорої межі.

Внутрішня прозора межа

Для цього ми не будемо створювати рамку, а спробуємо щось інше. Ми збираємося створити прозору внутрішню межу всередині наш образ. Можливо, це не дуже корисно в реальному сценарії, але це хороша практика з масками CSS.

Подібно до попереднього прикладу, ми будемо покладатися на два градієнти: a linear-gradient() для внутрішньої частини та a conic-gradient() для зовнішньої частини. Ми залишимо простір між ними, щоб створити ефект прозорої межі.

img {
  --b: 5px;  /* the border thickness */
  --d: 20px; /* the distance from the edge */

  --_g: calc(100% - 2 * (var(--d) + var(--b)));
  mask:
    conic-gradient(from 90deg at var(--d) var(--d), #0000 25%, #000 0)
      0 0 / calc(100% - var(--d)) calc(100% - var(--d)),
    linear-gradient(#000 0 0) 50% / var(--_g) var(--_g) no-repeat;
}
Вигадливі прикраси зображень: маски та розширені ефекти наведення

Можливо, ви помітили, що конічний градієнт у цьому прикладі має інший синтаксис, ніж у попередньому прикладі. Обидва мають створювати однакову форму, тож чому вони різні? Це тому, що ми можемо досягти того самого результату, використовуючи різні синтаксиси. Спочатку це може здатися незрозумілим, але це хороша функція. Ви не зобов'язані знаходити рішення для досягнення певної форми. Вам потрібно лише знайти одне рішення, яке працює для вас із багатьох можливостей.

Ось чотири способи створення зовнішнього квадрата за допомогою градієнтів:

Є ще більше способів зробити це, але ви зрозуміли суть.

Підходу Best™ не існує. Особисто я намагаюся знайти той, у якого найменший і найбільш оптимізований код. Для мене будь-яке рішення, яке вимагає менше градієнтів, менше обчислень і менше повторюваних значень, є найбільш прийнятним. Іноді я вибираю більш докладний синтаксис, оскільки це дає мені більше можливостей змінювати змінні та модифікувати речі. Це приходить з досвідом і практикою. Чим більше ви граєте з градієнтами, тим більше знаєте, який синтаксис використовувати та коли.

Давайте повернемося до нашої внутрішньої прозорої межі та заглибимося в ефект наведення. Якщо ви не помітили, є крутий ефект наведення, який пересуває цю прозору межу за допомогою a font-size трюк. Ідея полягає в тому, щоб визначити --d змінна зі значенням 1em. Ці змінні контролюють відстань межі від краю. Ми можемо перетворити так:

--_d: calc(var(--d) + var(--s) * 1em)

…надає нам наступний оновлений CSS:

img {
  --b: 5px;  /* the border thickness */
  --d: 20px; /* the distance from the edge */
  --o: 15px; /* the offset on hover */
  --s: 1;    /* the direction of the hover effect (+1 or -1)*/

  --_d: calc(var(--d) + var(--s) * 1em);
  --_g: calc(100% - 2 * (var(--_d) + var(--b)));
  mask:
    conic-gradient(from 90deg at var(--_d) var(--_d), #0000 25%, #000 0)
     0 0 / calc(100% - var(--_d)) calc(100% - var(--_d)),
    linear-gradient(#000 0 0) 50% / var(--_g) var(--_g) no-repeat;
  font-size: 0;
  transition: .35s;
}
img:hover {
  font-size: var(--o);
}

Команда font-size спочатку дорівнює 0 ,тому 1em також дорівнює 0 та --_d дорівнює --d. Однак при наведенні font-size дорівнює значенню, визначеному an --o змінна, яка встановлює зсув межі. Це, у свою чергу, оновлює --_d змінна, пересуваючи межу на зсув. Потім я додаю ще одну змінну, --s, щоб контролювати знак, який вирішує, чи переміщається межа всередину чи назовні.

Команда font-size трюк дійсно корисний, якщо ми хочемо анімувати властивості, які інакше не можна оживити. Спеціальні властивості, визначені за допомогою @property може вирішити це, але підтримка цього все ще бракує в той час, коли я це пишу.

Розкриття кадру

У першій частині цієї серії ми створили таку анімацію розкриття:

Ми можемо взяти ту саму ідею, але замість суцільної рамки ми використаємо такий градієнт:

Якщо ви порівняєте обидва коди, то помітите такі зміни:

  1. Я використав ту саму конфігурацію градієнта з першого прикладу всередині mask власність. Я просто переніс градієнти з background майно mask власність
  2. Я додав a repeating-linear-gradient() щоб створити межу градієнта.

Це воно! Я повторно використав більшу частину того самого коду, який ми вже бачили — із надзвичайно маленькими налаштуваннями — і отримав ще одне круте оформлення зображення з ефектом наведення.

/* Solid color border */

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

  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;
}
/* Gradient color border */

img {
  --b: 10px; /* the border thickness*/
  --g: 5px;  /* the gap on hover */
  background: repeating-linear-gradient(135deg, #F8CA00 0 10px, #E97F02 0 20px, #BD1550 0 30px);

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, #000 0;
  mask: 
    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,
    linear-gradient(#000 0 0) content-box;
  transition: .3s, mask-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, mask-size .3s .3s;
}

Давайте спробуємо іншу кадрову анімацію. Цей трохи складний, оскільки має a триетапна анімація:

Перший крок анімації — збільшити нижній край. Для цього ми регулюємо background-size з linear-gradient():

Вам, мабуть, цікаво, чому я також додаю верхній край. Це нам потрібно для третього кроку. Я завжди намагаюся оптимізувати код, який пишу, тому я використовую один градієнт, щоб охопити як верхню, так і нижню сторони, але верхній прихований і відкритий пізніше за допомогою mask.

Для другого кроку ми додаємо другий градієнт, щоб показати лівий і правий краї. Але цього разу ми робимо це за допомогою background-position:

Ми можемо зупинитися на цьому, оскільки ми вже маємо гарний ефект із двома градієнтами, але ми тут, щоб розширити межі, тому давайте додамо трохи маски, щоб досягти третього кроку.

Фокус полягає в тому, щоб зробити верхній край прихованим, доки ми не покажемо низ і боки, а потім оновити mask-size (Або mask-position), щоб показати верхню частину. Як я вже говорив раніше, ми можемо знайти багато конфігурацій градієнта для досягнення того самого ефекту.

Ось ілюстрація градієнтів, які я буду використовувати:

Я використовую два конічні градієнти, ширина яких дорівнює 200%. Обидва градієнти охоплюють область, залишаючи непокритою лише верхню частину (ця частина буде невидимою пізніше). При наведенні я пересуваю обидва градієнти, щоб покрити цю частину.

Ось краща ілюстрація одного з градієнтів, щоб краще зрозуміти, що відбувається:

Тепер ми поміщаємо це всередину mask майно, і ми готові! Ось повний код:

img {
  --b: 6px;  /* the border thickness*/
  --g: 10px; /* the gap */
  --c: #0E8D94;

  padding: calc(var(--b) + var(--g));
  --_l: var(--c) var(--b), #0000 0 calc(100% - var(--b)), var(--c) 0;
  background:
    linear-gradient(var(--_l)) 50%/calc(100% - var(--_i,80%)) 100% no-repeat,
    linear-gradient(90deg, var(--_l)) 50% var(--_i,-100%)/100% 200% no-repeat;  
  mask:
    conic-gradient(at 50% var(--b),#0000 25%, #000 0) calc(50% + var(--_i, 50%)) / 200%,
    conic-gradient(at 50% var(--b),#000 75%, #0000 0) calc(50% - var(--_i, 50%)) / 200%;
  transition: 
    .3s calc(.6s - var(--_t,.6s)) mask-position, 
    .3s .3s background-position,
    .3s var(--_t,.6s) background-size,
    .4s transform;
  cursor: pointer;
}
img:hover {
  --_i: 0%;
  --_t: 0s;
  transform: scale(1.2);
}

Я також ввів деякі змінні для оптимізації коду, але ви повинні звикнути до цього прямо зараз.

А як щодо чотириетапної анімації? Так, це можливо!

Немає пояснень, тому що це ваше домашнє завдання! Візьміть усе, про що ви дізналися в цій статті, щоб розібрати код і спробувати сформулювати, що він робить. Логіка подібна до всіх попередніх прикладів. Головне – виділити кожен градієнт, щоб зрозуміти кожен крок анімації. Я залишив код неоптимізованим, щоб полегшити читання. У мене є оптимізована версія якщо вам цікаво, але ви також можете спробувати оптимізувати код самостійно та порівняти його з моєю версією для додаткової практики.

Підводячи підсумок

Ось і все для частини 2 цієї серії з трьох частин про креативне декорування зображень за допомогою лише елемент. Тепер ми добре розуміємо, як поєднувати градієнти та маски для створення чудових візуальних ефектів і навіть анімації — без додаткових елементів або псевдоелементів. Так, єдиний тега достатньо!

У нас є ще одна стаття з цієї серії. А поки я використовую бонусну демо-версію з крутим ефектом наведення mask зібрати зламаний образ.

Серія Fancy Image Decorations

  • Магія одного елемента
  • Маски та розширені ефекти наведення (ти тут!)
  • Контури та складні анімації (наступає 28 жовтня )

Часова мітка:

Більше від CSS-хитрощі