Как работают CSS-треугольники? - PullRequest
1756 голосов
/ 16 августа 2011

Существует множество различных форм CSS на Трюки CSS - формы CSS , и я особенно озадачен треугольником:

CSS Triangle

#triangle-up {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
}
<div id="triangle-up"></div>

Как и почему это работает?

Ответы [ 17 ]

2165 голосов
/ 16 августа 2011

Треугольники CSS: трагедия в пяти действиях

Как сказал Алекс , границы равной ширины прилегают друг к другу под углом 45 градусов:

borders meet at 45 degree angles, content in middle

Когда у вас нет верхней границы, это выглядит так:

no top border

Тогда вы даете ему ширину 0 ...

no width

... и высота 0 ...

no height either

... и, наконец, вы делаете прозрачными две боковые границы:

transparent side borders

Это приводит к треугольнику.

497 голосов
/ 16 августа 2011

Границы используют угловой край, где они пересекаются (угол 45 ° с границами равной ширины, но изменение ширины границ может искажать угол).

Border example

jsFiddle .

Скрывая определенные границы, вы можете получить эффект треугольника (как вы можете видеть выше, делая разные части разными цветами). transparent часто используется в качестве цвета края для достижения треугольной формы.

457 голосов
/ 17 августа 2011

Начните с основного квадрата и границ.Каждой рамке будет присвоен свой цвет, поэтому мы можем отличить их друг от друга:

.triangle {
    border-color: yellow blue red green;
    border-style: solid;
    border-width: 200px 200px 200px 200px;
    height: 0px;
    width: 0px;
}

, что дает вам это :

square with four borders

Но верхняя граница не нужна, поэтому установите ее ширину 0px.Теперь наш нижний край 200px сделает наш треугольник высотой 200px.

.triangle {
    border-color: yellow blue red green;
    border-style: solid;
    border-width: 0px 200px 200px 200px;
    height: 0px;
    width: 0px;
}

и мы получим this :

bottom half of square with four borders

Затем, чтобы скрыть два боковых треугольника, установите цвет границы прозрачным.Так как верхняя граница была эффективно удалена, мы также можем установить прозрачный цвет верхней границы.

.triangle {
    border-color: transparent transparent red transparent;
    border-style: solid;
    border-width: 0px 200px 200px 200px;
    height: 0px;
    width: 0px;
}

наконец мы получаем this :

triangular bottom border

245 голосов
/ 17 июля 2014

Другой подход:

Треугольники CSS3 с поворотом преобразования

Треугольную форму довольно легко сделать с помощью этой техники. Для людей, которые предпочитают видеть анимацию, объясняющую, как работает эта техника, вот она:

gif animation : how to make a triangle with transform rotate

В противном случае, в 4 актах (это не трагедия) подробно объясняется, как сделать равнобедренный прямоугольный треугольник с одним элементом.

  • Примечание 1: для равнобедренных треугольников и необычных вещей вы можете увидеть шаг 4 .
  • Примечание 2: в следующих фрагментах префиксы поставщиков не включены. они включены в кодовых демонстраций .
  • Примечание 3: HTML-код для следующего объяснения всегда: <div class="tr"></div>

ШАГ 1: Сделать div

Легко, просто убедитесь, что width = 1.41 x height. Вы можете использовать любую технику ( см. Здесь ), включая использование процентов и отступа для поддержания соотношения сторон и создания адаптивного треугольника . На следующем изображении div имеет золотисто-желтую рамку.

В этот div вставьте псевдоэлемент и задайте ему 100% ширину и высоту родительского элемента. Псевдоэлемент имеет синий фон на следующем изображении.

Making a CSS triangle with transform roate step 1

На данный момент у нас есть CSS :

.tr {
    width: 30%;
    padding-bottom: 21.27%; /* = width / 1.41 */
    position: relative;
}

.tr: before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #0079C6;
}

ШАГ 2: Давайте вращаться

Во-первых, самое важное: определить начало преобразования . Исходное значение по умолчанию находится в центре псевдоэлемента, и оно нам нужно внизу слева. Добавив CSS к псевдоэлементу:

transform-origin:0 100%; или transform-origin: left bottom;

Теперь мы можем повернуть псевдоэлемент на 45 градусов по часовой стрелке с помощью transform : rotate(45deg);

Creating a triangle with CSS3 step 2

На данный момент у нас есть CSS :

.tr {
    width: 30%;
    padding-bottom: 21.27%; /* = width / 1.41 */
    position: relative;
}

.tr:before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #0079C6;
    transform-origin: 0 100%;        
    transform: rotate(45deg);
}

ШАГ 3: скрыть

Чтобы скрыть ненужные части псевдоэлемента (все, что переполняет div с желтой рамкой), вам просто нужно установить overflow:hidden; на контейнере. после удаления желтой рамки вы получаете ... a TRIANGLE ! :

DEMO

CSS triangle

CSS:

.tr {
    width: 30%;
    padding-bottom: 21.27%; /* = width / 1.41 */
    position: relative;
    overflow: hidden;
}

.tr:before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #0079C6;
    transform-origin: 0 100%;
    transform: rotate(45deg);
}

ШАГ 4: идти дальше ...

Как показано в демоверсии , вы можете настроить треугольники:

  1. Сделайте их тоньше или лестнее, играя с skewX().
  2. Сделайте так, чтобы они указывали влево, вправо или любое другое направление, играя с направлением преобразования и направлением вращения.
  3. Сделайте некоторое отражение со свойством трехмерного преобразования.
  4. Дайте границы треугольника
  5. Поместите изображение внутри треугольника
  6. Гораздо больше ... Раскройте возможности CSS3 !

Зачем использовать эту технику?

  1. Треугольник может легко реагировать.
  2. Вы можете сделать треугольник с рамкой .
  3. Вы можете поддерживать границы треугольника. Это означает, что вы можете вызвать состояние наведения или щелчок, только когда курсор находится в треугольнике внутри . Это может стать очень удобным в некоторых ситуациях, таких как эта , где каждый треугольник не может перекрывать своих соседей, поэтому каждый треугольник имеет свое собственное состояние наведения.
  4. Вы можете сделать некоторые причудливые эффекты, такие как отражения .
  5. Это поможет вам понять свойства 2D и 3D-преобразования.

Почему бы не использовать эту технику?

  1. Основным недостатком является совместимость браузера , свойства 2d-преобразования поддерживаются IE9 +, и поэтому вы не можете использовать эту технику, если планируете поддерживать IE8.См. CanIuse для получения дополнительной информации.Для некоторых причудливых эффектов, использующих 3d-преобразования, такие как , браузер отражения поддерживает IE10 + (см. canIuse для получения дополнительной информации).
  2. Вам не нужно ничего адаптивного и простогоТреугольник - это хорошо для вас, тогда вы должны использовать технику границ, описанную здесь: лучшая совместимость с браузером и более легкая для понимания благодаря удивительным публикациям здесь.
175 голосов
/ 29 ноября 2011

Вот анимация в JSFiddle , которую я создал для демонстрации.

Также см. Фрагмент ниже.

Это анимированный GIF из скринкаста

Animated Gif of Triangle

transforms = [
         {'border-left-width'   :'30', 'margin-left': '70'},
         {'border-bottom-width' :'80'},
         {'border-right-width'  :'30'},
         {'border-top-width'    :'0', 'margin-top': '70'},
         {'width'               :'0'},
         {'height'              :'0', 'margin-top': '120'},
         {'borderLeftColor'     :'transparent'},
         {'borderRightColor'    :'transparent'}
];


$('#a').click(function() {$('.border').trigger("click");});
(function($) {
    var duration = 1000
    $('.border').click(function() {
		  for ( var i=0; i < transforms.length; i++ ) {
        $(this)
         .animate(transforms[i], duration)
		  }
    }).end()
}(jQuery))
.border {
    margin: 20px 50px;
    width: 50px;
    height: 50px;
    border-width: 50px;
    border-style: solid;
    border-top-color: green;
    border-right-color: yellow;
    border-bottom-color: red;
    border-left-color: blue;
    cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>

Случайная версия

/**
 * Randomize array element order in-place.
 * Using Durstenfeld shuffle algorithm.
 */
function shuffleArray(array) {
    for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
}

transforms = [
         {'border-left-width'   :'30', 'margin-left': '70'},
         {'border-bottom-width' :'80'},
         {'border-right-width'  :'30'},
         {'border-top-width'    :'0', 'margin-top': '70'},
         {'width'               :'0'},
         {'height'              :'0'},
         {'borderLeftColor'     :'transparent'},
         {'borderRightColor'    :'transparent'}
];
transforms = shuffleArray(transforms)



$('#a').click(function() {$('.border').trigger("click");});
(function($) {
    var duration = 1000
    $('.border').click(function() {
		  for ( var i=0; i < transforms.length; i++ ) {
        $(this)
         .animate(transforms[i], duration)
		  }
    }).end()
}(jQuery))
.border {
    margin: 50px;
    width: 50px;
    height: 50px;
    border-width: 50px;
    border-style: solid;
    border-top-color: green;
    border-right-color: yellow;
    border-bottom-color: red;
    border-left-color: blue;
    cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>

Все сразу версия

$('#a').click(function() {$('.border').trigger("click");});
(function($) {
    var duration = 1000
    $('.border').click(function() {
        $(this)
         .animate({'border-top-width': 0            ,
         					 'border-left-width': 30          ,
         					 'border-right-width': 30         ,
         					 'border-bottom-width': 80        ,
         					 'width': 0                       ,
         					 'height': 0                      ,
                   'margin-left': 100,
                   'margin-top': 150,
         					 'borderTopColor': 'transparent',
         					 'borderRightColor': 'transparent',
         					 'borderLeftColor':  'transparent'}, duration)
    }).end()
}(jQuery))
.border {
    margin: 50px;
    width: 50px;
    height: 50px;
    border-width: 50px;
    border-style: solid;
    border-top-color: green;
    border-right-color: yellow;
    border-bottom-color: red;
    border-left-color: blue;
    cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>
47 голосов
/ 17 июня 2014

Допустим, у нас есть следующий div:

<div id="triangle" />

Теперь измените CSS шаг за шагом, чтобы вы получили ясное представление о том, что происходит вокруг

ШАГ 1: JSfiddle Link:

 #triangle {
        background: purple;
        width :150px;
        height:150PX;
        border-left: 50px solid black ;
        border-right: 50px solid black;
        border-bottom: 50px solid black;
        border-top: 50px solid black;
    }

Это простой div. С очень простым CSS. Так что непрофессионал может понять. Div имеет размеры 150 х 150 пикселей с границей 50 пикселей. Изображение прилагается:

enter image description here

ШАГ 2: JSfiddle Link:

#triangle {
    background: purple;
    width :150px;
    height:150PX;
    border-left: 50px solid yellow ;
    border-right: 50px solid green;
    border-bottom: 50px solid red;
    border-top: 50px solid blue;
}

Теперь я только что изменил цвет границы всех четырех сторон. Изображение прилагается.

enter image description here

ШАГ: 3 JSfiddle Link:

#triangle {
    background: purple;
    width :0;
    height:0;
    border-left: 50px solid yellow ;
    border-right: 50px solid green;
    border-bottom: 50px solid red;
    border-top: 50px solid blue;
}

Теперь я просто изменил высоту и ширину div с 150 пикселей на ноль. Изображение прилагается

enter image description here

ШАГ 4: JSfiddle:

#triangle {
    background: purple;
    width :0px;
    height:0px;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 50px solid red;
    border-top: 50px solid transparent;
}

Теперь я сделал все границы прозрачными, кроме нижней границы. Изображение прикреплено ниже.

enter image description here

ШАГ 5: JSfiddle Link:

#triangle {
    background: white;
    width :0px;
    height:0px;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 50px solid red;
    border-top: 50px solid transparent;
}

Теперь я просто изменил цвет фона на белый. Изображение прилагается.

enter image description here

Следовательно, мы получили нужный нам треугольник.

38 голосов
/ 01 декабря 2014

А теперь что-то совершенно другое ...

Вместо использования трюков css не забывайте о таких простых решениях, как html-сущности:

&#9650;

Результат:

См .: Что такое сущности HTML для треугольников вверх и вниз?

31 голосов
/ 21 марта 2013

Рассмотрим нижеприведенный треугольник

.triangle {
    border-bottom:15px solid #000;
    border-left:10px solid transparent;
    border-right:10px solid transparent;
    width:0;
    height:0;
}

Это то, что нам дано:

Small triangle output

Почему он вышел в такой форме? Приведенная ниже диаграмма поясняет размеры, обратите внимание, что для нижней границы использовалось 15 пикселей, а для левой и правой - 10 пикселей.

Large triangle

Довольно просто сделать прямоугольный треугольник, удалив правую границу.

Right angle triangle

29 голосов
/ 30 декабря 2011

Сделав еще один шаг вперед, используя css, я добавил стрелки к кнопкам «Назад» и «Вперед» (да, я знаю, что это не 100% кросс-браузер, но, тем не менее, приятный ход).

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
  margin:20px auto;
}

.triangle-down {
  border-bottom:none;
  border-top: 100px solid red;
}

.triangle-left {
  border-left:none;
  border-right: 100px solid red;
  border-bottom: 50px solid transparent;
  border-top: 50px solid transparent;
}

.triangle-right {
  border-right:none;
  border-left: 100px solid red;
  border-bottom: 50px solid transparent;
  border-top: 50px solid transparent;
}

.triangle-after:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid red;
  margin:0 5px;
  content:"";
  display:inline-block;
}

.triangle-after-right:after {
  border-right:none;
  border-left: 5px solid blue;
  border-bottom: 5px solid transparent;
  border-top: 5px solid transparent;

}

.triangle-before:before {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid blue;
  margin:0 5px;
  content:"";
  display:inline-block;
}

.triangle-before-left:before {
  border-left:none;
  border-right: 5px solid blue;
  border-bottom: 5px solid transparent;
  border-top: 5px solid transparent;

}
<div class="triangle"></div>
<div class="triangle triangle-down"></div>
<div class="triangle triangle-left"></div>
<div class="triangle triangle-right"></div>

<a class="triangle-before triangle-before-left" href="#">Back</a>
<a class="triangle-after triangle-after-right" href="#">Next</a>
18 голосов
/ 26 июля 2013

Другой подход.С линейным градиентом (для IE только IE 10+).Вы можете использовать любой угол:

.triangle {
    margin: 50px auto;
    width: 100px;
    height: 100px;
/* linear gradient */
    background: -moz-linear-gradient(-45deg,  rgba(255,0,0,0) 0%, rgba(255,0,0,0) 50%, rgba(255,0,0,1) 50%, rgba(255,0,0,1) 100%);
 /* FF3.6+ */
    background: -webkit-gradient(linear, left top, right bottom, color-stop(0%,rgba(255,0,0,0)), color-stop(50%,rgba(255,0,0,0)), color-stop(50%,rgba(255,0,0,1)), color-stop(100%,rgba(255,0,0,1)));
 /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(-45deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(-45deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* Opera 11.10+ */
    background: -ms-linear-gradient(-45deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* IE10+ */
    background: linear-gradient(135deg,  rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);
 /* W3C */;
}
<div class="triangle"></div>

Вот jsfiddle

...