#html #css
Надо мне сверстать рамку с уголком подобного вида: Подобных вопросов и на ru so и в сети находится достаточно, чтобы на чистом css и без картинок. Сделал по гайдлайнам что-то типа: .sticky { width: 20rem; } .sticky div { position:relative; background-color: #FFFFCC; padding: 1rem 2rem; box-shadow:0 1px 1px rgba(0,0,0,0.2), -1px 1px 1px rgba(0,0,0,0.1); } .sticky div:before { content:""; position:absolute; top:0; right:0; border-width:0 16px 16px 0; border-style:solid; border-color:#FFFF99 #fff; box-shadow:0 1px 1px rgba(0,0,0,0.1), -1px 1px 1px rgba(0,0,0,0.01); }Я не понял, как сделать диагональную линию, но в принципе, накидав побольше теней получил вполне устраивающий результат в Firefox: Но когда я открываю это всё в Chrome я вижу какую-то уродливую тень, заметную невооружённым глазом (потом пересматривая в FF под лупой вижу, что и там она есть, но не так сильно бросается в глаза) Выключена внешняя тень, оставлена тень от уголка: Выключена тень от уголка, оставлена внешняя тень: Без теней листочек получается какой-то бедный с изобразительной точки зрения, ненастоящий, поэтому у меня возникает следующий вопрос: как кроссбраузерно сделать тень только слева и снизу и чтобы сверху и справа не было не было артефактов?
Ответы
Ответ 1
Box-shadow: blur & spread Используя свойство box-shadow, чаще всего указывают всего три параметра: смещение по X, смещение по Y и размер размытия (blur). При этом незаслуженно забывая ещё об одном параметре — spread. В разных мануалах, его называют по-разному — распространение или сжатие — скорее всего, это потому, что параметр может принимать, как положительные значения, так и отрицательные, в зависимости от задач. А также потому, что например, в Chrome этот параметр нельзя выставить меньше нуля нативным средством в инспекторе стилей (хотя, прописав значение вручную, всё прекрасно отображается и работает, если не двигать ползунок): Так что же делает этот параметр? Интерактивный пример, расставляет всё по местам: .controls{display:flex;justify-content:space-around;text-align:center}.controls input{display:block}:root{--cx:0;--cy:0;--sb:50px;--ss:0}.example{margin:15px auto;width:350px;height:70px;line-height:70px;text-align:center;box-sizing:border-box;border:4px solid #fa0;background-color:rgba(255,255,255,0);box-shadow:var(--cx) var(--cy) var(--sb) var(--ss) rgba(0,0,0,0.5)}offset_X (-n...n)смещение по Xoffset_Y (-n...n)смещение по Yblur (0...n)размытиеspread (-n...n)распространениеrgba(0, 0, 0, 0.5) 0px 0px 50px 0pxПодведём итоги наблюдений: Смещения — могут быть, как положительными, так и отрицательными; Размытие — это не размер тени, хотя и влияет на её размер визуально. Размытие как бы смазывает границу тени. Может принимать только положительное значение; Распространение — это размер тени, относительно блока, который её отбрасывает. Может принимать, как положительные, так и отрицательные значения. Отрицательное значение не может быть меньше половины меньшего из размеров блока. Например, если height блока 70px, то при значении spread меньше -34px тень просто схлопнется (70 / 2 - 35 = 0). При этом, исчезнет и её размытие, каким бы большим оно ни было, т.к. размывать нечего. После небольшого отступления в теорию, переходим к ответу на вопрос: body { background-color: #d4ebf7; } .sticky, .sticky_right { /* Здесь добавил и изменил стили только для сниппета */ width: 18rem; float: left; margin: 3px; } /********************** * Исправленный стикер * **********************/ .sticky div { position: relative; background-color: #FFFFCC; padding: 1rem 2rem; } .sticky div:before { content: ''; position: absolute; top: 0; right: 0; z-index: 1; border-width: 0 16px 16px 0; border-style: solid; border-color: #FFFF99 #fff; box-shadow: -1px 2px 2px -1px rgba(0, 0, 0, 0.3); } .sticky div:after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; z-index: -1; box-shadow: -2px 3px 3px -1px rgba(0, 0, 0, 0.3); } /******************** * Правильный стикер * ********************/ .sticky_right div { position: relative; /* Фон изменён со сплошного на градиент */ background-image: linear-gradient(225deg, transparent 10px, #FFFFCC 10px); padding: 1rem 2rem; } .sticky_right div:before { content: ''; position: absolute; top: 0; right: 0; z-index: 1; border-width: 0 16px 16px 0; border-style: solid; /* Цвет изменён с белого на прозрачный */ border-color: #FFFF99 transparent; box-shadow: -1px 2px 2px -1px rgba(0, 0, 0, 0.3); } .sticky_right div:after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; z-index: -1; box-shadow: -2px 3px 3px -1px rgba(0, 0, 0, 0.3); }Алгоритм прост, изменения минимальны: :before — в свойстве box-shadow с помощью параметра spread уменьшаем размер тени, но при этом сдвигаем тень ещё больше, в том же направлении, куда она была сдвинута ранее. Добавляем положительный z-index, на всякий случай. :after — добавляем. Выравниваем по левому и нижнему краю. Растягиваем по размерам родителя. Позиционируем с помощью отрицательного z-index за блоком. С box-shadow проводим те же манипуляции, что и с предыдущим блоком — уменьшаем тень четвёртым параметром и сдвигаем влево вниз. Таким образом, за счёт смещений, тень осталась на своём месте, но из-за отрицательного распространения, стала меньше и спряталась под основной блок на противоположных от направления смещений краях. PS Т.к. была замечена, на мой взгляд, ещё одна недоработка — непрозрачность в месте отгиба — добавил рядом ещё вариант для сравнения. Кроссбраузерность напрямую зависит от поддержки linear-gradient.
Комментариев нет:
Отправить комментарий