x
 
Фёдор Волков
17 января 2019
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

Продолжение


В про­шлом совете мы разо­брали про­стые слу­чаи. Теперь попро­буем собрать такую же кнопку, но с про­зрач­ным фоном.

Для начала вос­ста­но­вим кнопку:

/* html */
​        
<button class="button">
  Кнопка
</button>
/* css */
​
/* Кнопка */
.button {
  height: 60px;
  border: 0;
  font-size: 20px;
  text-transform: uppercase;
  background-image: linear-gradient(
    to right, 
    #45aee5 0%, 
    #6be492 100%
  );
}

Вме­сто того, чтобы зали­вать кнопку фоно­вым цве­том, возь­мём под­хо­дя­щую маску:

И нало­жим её на нашу кнопку:

/* css */
​
.button {
  /* ... */
  mask-image: url("border-mask.svg");
}

У полу­чив­шейся кнопки две про­блемы. Во‑пер­вых, текст стал неви­ди­мым, так как он тоже попал под маску. Во‑вто­рых, при изме­не­нии ширины кнопки, рамка деформируется.

Испра­вим пер­вый недо­ста­ток. Для этого выне­сем фон на отдель­ный слой:

/* html */
​        
<button class="button">
  <span class="button-background"></span>
  Кнопка
</button>
/* css */
​
.button {
  /* ... */
  position: relative;
}
​        
.button-background {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-image: linear-gradient(
    to right, 
    #45aee5 0%, 
    #6be492 100%
  );
}

Чтобы испра­вить вто­рой недо­ста­ток, при­дётся пово­зиться и вспом­нить вре­мена олдскуль­ного скруг­ле­ния угол­ков.

Рас­пи­лим нашу маску на три части:

И при­ме­ним все три маски:

/* css */
​        
.button-background {
  mask-image: url("border-left.svg"), 
    url("border-right.svg"),
    url("border-center.svg");
  mask-position: center left, center right, center center;
  mask-repeat: no-repeat, no-repeat, repeat-x;
  mask-size: contain, contain, contain;
}

К сожа­ле­нию, цен­траль­ная часть рамки выле­зает из своих гра­ниц. Выне­сем её на отдель­ный слой и зада­дим ему отступы:

/* html */
​        
<button class="button">
  <span class="button-sides"></span>
  <span class="button-center"></span>
  Кнопка
</button>
/* css */
​        
.button-sides {
  /* ... */
  mask-image: url("border-left.svg"), url("border-right.svg");
  mask-position: center left, center right;
  mask-repeat: no-repeat, no-repeat;
  mask-size: contain, contain;
}

.button-center {
  /* ... */
  left: 30px;
  right: 30px;
  mask-image: url("border-center.svg");
  mask-position: center;
  mask-repeat: repeat-x;
  mask-size: contain;
}

Цен­траль­ная часть на месте. Но, если при­смот­реться, то видно, что гра­ди­ент у цен­траль­ной части рамки начи­на­ется не с того оттенка:

Дело в том, что ширина цен­траль­ной части уже, чем ширина самой кнопки. Это ста­но­вится замет­нее, если убрать маску:

Чтобы это побе­дить, рас­тя­нем фон цен­траль­ной части так, чтобы он по длине сов­па­дал с кноп­кой. Для этого пере­не­сём фон на псев­до­эле­мент и вытя­нем его влево и вправо:

/* css */
​        
.button-center {
  /* ... */
  left: 30px;
  right: 30px;
  mask-image: url("border-center.svg");
  mask-position: center;
  mask-repeat: repeat-x;
  mask-size: contain;
  background: none;
}

.button-center::before {
  position: absolute;
  top: 0;
  bottom: 0;
  right: -30px;
  left: -30px;
  background-image: linear-gradient(
    to right, 
    #45aee5 0%, 
    #6be492 100%
  );
  content: '';
}

Готово. Если вы зна­ете, как сде­лать такую кнопку проще, пишите в комментарии.

P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.
Вёрстка и прототипирование — дисциплина Школы дизайнеров. Набор открыт до 12 августа или пока есть свободные места.
 

Поделиться
Отправить

Комментарии

Евгений Закурдаев
17 января 2019

Могу предложить следующий вариант:

<svg width="0" height="0">   <linearGradient id="gradient" x1="0" x2="1" y1="0" y2="0">     <stop offset="0"/>     <stop offset="1"/>   </linearGradient>   <symbol id="border" overflow="visible">     <rect width="100%" height="100%" rx="30px" ry="30px"/>   </symbol> </svg> <button class="button">   <svg class="button__border"><use href="#border"/></svg>   Кнопка </button>


css .button {   position: relative;   height: 60px;   border: 0;   background: transparent; } ​ .button__border {   position: absolute;   top: 0;   left: 0;   overflow: visible;   width: 100%;   height: 100%;   fill: none;   stroke: url(#gradient);   stroke-width: 4px; } ​ #gradient stop:nth-child(1) {   stop-color: #45aee5; } ​ #gradient stop:nth-child(2) {   stop-color: #6be492; }

Радомир Купфер
17 января 2019

Можно обойтись без масок и отдельных ресурсов: https://codepen.io/wingerie/pen/qLGOea


17 января 2019

Радомир, ваш вариант совпадает с описанным в прошлом совете:
https://bureau.ru/soviet/20190103/

Это решение работает только в случае, когда фон заранее известен. Если добавить случайный фон к вашему решению, получится так:


Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры. Мы ожидаем, что такие комментарии составят около 20% от общего числа.

Решение о публикации принимается один раз; мы не имеем возможности комментировать или пересматривать свое решение, хотя оно может быть ошибочно. Уже опубликованные комментарии могут быть удалены через некоторое время, если без них обсуждение не становится менее ценным или интересным.

Вот такой веб 2.0.

Как менеджеру ставить задачи, чтобы ротация в команде не заставляла пережёвывать все задачи устно по 100 раз? Режимы наложения в ЦСС 2 Есть ли смысл учить Ruby on Rails в 2019 году? 3 Где провести границу MVP? 1




Недавно всплыло

2 Как найти себе замену 1 Хочу научиться сторителлингу 2 2