CSS: искажать границу кнопки, а не текст

Я ищу простой способ с одним тегом (просто <a>), чтобы создать эффект перекоса на границах, но оставить текст таким, какой он есть.

Я бы знал, как сделать с интервалом внутри или снаружи, но я не хочу иметь дополнительный HTML-код, практически не имеющий смысла, на странице.

Пример ниже.

введите здесь описание изображения


person Sander Schaeffer    schedule 10.06.2015    source источник


Ответы (4)


Вы можете изменить наклон дочернего элемента, т. е. указать противоположные координаты наклона, как вы указали для родительского элемента.

Вот рабочий пример

Предположим, у вас есть ниже, как вы html,

<div class="btn">
    <button><div class="btn-text">Click</div></button>
</div>

Если мы искажаем родительский элемент на 20deg, то мы должны искажать дочерний элемент на -20deg, т.к.

.btn {
    -ms-transform: skewX(20deg); /* IE 9 */
    -webkit-transform: skewX(20deg); /* Safari */
    transform: skewX(20deg);
}
.btn-text {
    -ms-transform: skewX(-20deg); /* IE 9 */
    -webkit-transform: skewX(-20deg); /* Safari */
    transform: skewX(-20deg);
    padding: 20px;
}
person Saumil    schedule 10.06.2015
comment
мне тоже нравится этот ответ, два хороших ответа на одну и ту же проблему, хотя я бы, вероятно, выбрал треугольники css, так как это меньше HTML: -P - person Toni Leigh; 11.06.2015
comment
Просто предположение, но не проще ли было бы, чтобы html выглядел как ‹a href=#›‹span›text‹/span›‹/a›? Таким образом, у вас нет двух отдельных классов/элементов HTML (диапазон отсутствует). Однако CSS может остаться прежним. Кроме того: используйте классы, а не идентификаторы. :) Спасибо за ваш вклад! - person Sander Schaeffer; 11.06.2015
comment
С небольшой помощью вашего CSS я использовал метод span, как я предложил выше. Мне пришлось добавить display: inline-block как для элемента привязки, так и для элемента span, поскольку они не являются встроенными элементами. Но теперь работает отлично! :) - person Sander Schaeffer; 11.06.2015
comment
@SanderSchaeffer - классы, вероятно, лучше всего, тогда вы можете повторно использовать стиль для других элементов, и это не вызовет проблем, если вы решите по какой-то причине изменить внутренний элемент, например <a class='skew-outer'><span class='skew-inner' ... - person Toni Leigh; 11.06.2015
comment
@SanderSchaeffer Тони Ли, да, классы намного лучше, когда вы хотите повторно использовать материал, у меня есть дурная привычка иногда не думать о повторном использовании классов. Обновил ответ. - person Saumil; 11.06.2015

Вы можете просто добиться желаемого эффекта, используя трюки треугольника CSS. Просто добавьте несколько стилей для псевдоклассов ::before и ::after.

.skewed_button {
    background: #32CD32;
    color: #000;
    text-decoration: none;
    font-size: 20px;
    display: inline-block;
    height: 30px;
    margin-left: 15px;
    padding: 6px 10px 0;
}
.skewed_button::before {
    content: "";
    float: left;
    margin: -6px 0 0 -25px;
    border-left: 15px solid transparent;
    border-bottom: 36px solid #32CD32;  
    height: 0px;
}
.skewed_button::after {
    content: "";
    float: right;
    margin: -6px -25px 0 0 ;
    border-left: 15px solid #32CD32;
    border-bottom: 36px solid transparent;  
    height: 0px;
}
<a href="#some_url" class="skewed_button">Some Text</a>

person Vadym Pechenoha    schedule 10.06.2015
comment
почему одна граница белая, а другая прозрачная? Кроме того, почему у каждого треугольника есть -6px верхнего поля и разное количество левого и правого полей? - person Toni Leigh; 11.06.2015
comment
Это была просто ошибка. Я изменил его на прозрачный. Существуют разные поля для верхнего и левого/правого полей, потому что нам нужно вертикальное выравнивание текста по центру, поэтому нужно добавить верхнее поле (с -6px это выглядит хорошо). И -25px для левого/правого: 15px - это размер треугольника, а 10px - просто добавьте пробел между текстом и треугольниками. - person Vadym Pechenoha; 11.06.2015
comment
Я предполагаю, что невозможно автоматически сравнять высоту самой кнопки? Скорее всего, все кнопки будут иметь одинаковую высоту, так как размер шрифта не изменится.. но все же. Это было бы чудесно. - person Sander Schaeffer; 11.06.2015
comment
Возможно, @SanderSchaeffer - посмотрите первую скрипту js в моем ответе - попробуйте изменить значения на % и посмотреть, что произойдет, хотя я не уверен насчет ширины псевдоэлементов, с чем они будут сравниваться? Единицы Vw могли бы работать, если бы они также использовались на кнопке, и вы не возражали бы против изменения размера с окном просмотра! - person Toni Leigh; 11.06.2015
comment
Это нормально, но не будет хорошо масштабироваться. Если вам нужен адаптивный текст и т. д., то он будет включать в себя некоторую степень боли для поддержания - person GorillaApe; 10.04.2016

Одним из решений является использование треугольников CSS на :before и :after. Это решение оставляет самый чистый HTML.

Этот jsfiddle демонстрирует

.is-skewed {
    width: 80px;
    height: 40px;
    background-color: #f07;
    display: block;
    color: #fff;
    margin-left: 40px;
}

.is-skewed:before,
.is-skewed:after {
    content: '';
    width: 0;
    height: 0;
}

.is-skewed:before {
    border-bottom: 40px solid #f07;
    border-left: 20px solid transparent;
    float:left;
    margin-left: -20px;
}

.is-skewed:after {
    border-top: 40px solid #f07;
    border-right: 20px solid transparent;
    float:right;
    margin-right: -20px;
}

Треугольники CSS используют толстые границы для элементов с размерами 0, а точки, в которых границы встречаются, образуют диагональную линию, необходимую для треугольника (хорошая визуализация — это посмотреть на , где две границы встречаются и образуют треугольники). Важно, чтобы одна граница была прозрачной, а другая — цветной, и чтобы они были смежными (то есть слева и сверху, а не слева и справа). Вы можете настроить размер, ориентацию и длину сторон, играя с размерами границ.

Для вашей кнопки мы также используем числа с плавающей запятой и отрицательные поля, чтобы вывести их за пределы элемента и правильно выровнять. Абсолютное положение и отрицательные левые и правые значения также были бы хорошим решением для позиционирования

Вы также можете использовать :hover состояния.

.is-skewed:hover {
    background-color: #40f;
}
.is-skewed:hover:after {
    border-top-color: #40f;    
}
.is-skewed:hover:before {
    border-bottom-color: #40f;
}

Важно отметить использование background-color и border-color, а также то, что :hover стоит первым во всех соответствующих селекторах. Если бы наведение было вторым, это произошло бы

person Toni Leigh    schedule 10.06.2015

Вы также можете использовать clip-path для этого, например:

clip-path: polygon(14px 0%, 100% 0%, calc(100% - 14px) 100%, 0% 100%);

.skewed_button {
    background: yellow;
    text-decoration: none;
    display: inline-block;
    padding: 10px 20px;
    clip-path: polygon(14px 0%, 100% 0%, calc(100% - 14px) 100%, 0% 100%);
}
<a href="" class="skewed_button">Some Text</a>

person uNmAnNeR    schedule 20.10.2020