Данный Ribbon — это изображение внутри ссылки с абсолютным позиционированием. Чем меня не устраивает данный вариант? Во-первых: я очень люблю современные стандарты CSS, с помощью которых можно создать приятный дизайн, используя минимум изображений, а в данном случае лентой может быть обычный блок с transform rotate
. Во-вторых: с недавнего времени я смотрю на веб сквозь Retina дисплей и неоптимизированные img
сразу же бросаются в глаза, но и разработчикам обращать внимание на какую то ленточку, оптимизировать ее отображение с media queries, мне кажеться, даже немного смешно.
Создадим блок длинной 500px, высотой 50px, с абсолютным позиционированием, сверху, слева. Получится то, что мы видим на изображении ниже в левой части. Далее, повернем блок на -45 градусов, чтобы у нас получилось что-то похожее на Ribbon с LESS. Результат показан в правой части изображения. Наш элемент вращается от своего центра, вследствие чего получается отступ слева, а часть будущей ленты выезжает за рабочую область.
С помощью инспектора мы можем подобрать нужные нам значения для top
и -left
. Чем меня не устраивает данный вариант? Во-первых — перфекционизм: я хочу, чтобы максимальное количество указанных пикселей (в данном случае 500) отображалось в рабочей области и не выезжало за нее. Во-вторых — лень: я не хочу при изменении позиции (top, right, bottom, left) и градуса наклона вручную подбирать значения, чтобы спрятать все углы.
Геометрия
Как я и сказал, поворот элемента выполняется от центра. Следовательно, и значения отступов измеряются от края рабочей области до центра. Мысленно представим образующиеся фигуры — треугольники, стороны которых нам необходимо вычислить:
Получилось два треугольника ABC и A2B2C2, стороны которых нам необходимо вычислить. Нам известно, что С = 500px (width), С2 = 50px (height), угол наклона -65 (deg), следовательно, угол a в треугольнике ABC равен 65 градусам, а угол b — 25 градусам (180 — 90 — 65). В треугольнике A2B2C2 углы a2 и b2 равны 65 и 25 градусам соответственно.
Тригонометрия
Все просто. Синус угла равен отношению противолежащего катета к гипотинузе. Следовательно:
A = sin(a) * C или A = sin(65) * 500;
B = sin(b) * C или B = sin(25) * 500;
A2 = sin(a2) * C2 или A2 = sin(65) * 50;
B2 = sin(b2) * C2 или B2 = sing(25) * 50;
LESS
.MojoRibbon(@width, @height, @deg, @valign) { width: @width; height: @height; -webkit-box-sizing: border-box; /* Что бы высота не изменялась при padding */ -moz-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; .defineDegree(@deg, @valign) when (@deg < 0) and (@valign = top) { @degree: -@deg; /* Угол треугольника неотрицательный, вычисляем правильный sin */ top: @countHeight; left: @countWidth; -webkit-transform: rotate(@deg); -moz-transform: rotate(@deg); -o-transform: rotate(@deg); -ms-transform: rotate(@deg); transform: rotate(@deg); }; .defineDegree(@deg, @valign) when (@deg < 0) and (@valign = bottom) { @degree: -@deg; /* Угол треугольника неотрицательный, вычисляем правильный sin */ bottom: @countHeight; right: @countWidth; /* Если угол поворота отрицательный и в вертикали объект позицианируется по нижнему краю, логически правильно в горизонтали позицианировать его по правому краю */ -webkit-transform: rotate(@deg); -moz-transform: rotate(@deg); -o-transform: rotate(@deg); -ms-transform: rotate(@deg); transform: rotate(@deg); }; .defineDegree(@deg, @valign) when (@deg > 0) and (@valign = top) { @degree: @deg; top: @countHeight; right: @countWidth; -webkit-transform: rotate(@degree); -moz-transform: rotate(@degree); -o-transform: rotate(@degree); -ms-transform: rotate(@degree); transform: rotate(@degree); }; .defineDegree(@deg, @valign) when (@deg > 0) and (@valign = bottom) { @degree: @deg; bottom: @countHeight; left: @countWidth; /* Если угол поворота положительный и в вертикали объект позицианируется по верхнему краю, логически правильно в горизонтали позицианировать его по левому краю */ -webkit-transform: rotate(@degree); -moz-transform: rotate(@degree); -o-transform: rotate(@degree); -ms-transform: rotate(@degree); transform: rotate(@degree); }; .defineDegree(@deg, @valign) when (@deg = 0) { @degree: @deg; top: 0; left: 0; }; .defineDegree(@deg, @valign); @angleB: 90-@degree; @angleB2: @angleB; @sideA: round(sin(@degree), 3)*@width; /* Сторона А */ @sideB: round(sin(@angleB), 3)*@width; /* Сторона B */ @sideB2: round(sin(@angleB2), 3)*@height; /* Сторона А2 */ @sideA2: round(sin(@degree), 3)*@height; /* Сторона B2 */ @countHeight: @sideA/2 - @height/2 - @sideB2/2; @countWidth: -((@width)-(@sideB))/2 - @sideA2/2; }
Большое спасибо всем таким же, как и я CSS занудам за внимание.
ссылка на оригинал статьи http://habrahabr.ru/post/186386/
Добавить комментарий