#html #css #bootstrap-4
#HTML #css #css-формы
Вопрос:
Я пытаюсь создать метку стрелки, используя css :after
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
left: 100%;
width: 0;
height: 0;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
border-left: 25px solid red;
}
<div class="one-line">text<br>text<br></div>
Я хочу, чтобы элемент after имел ту же высоту, что и родительский, как я могу это сделать с помощью css или js?
Примечание: текст внутри метки заполняется динамически. [Максимальная длина текста: 2 строки]
Как я думаю, может оказаться невозможным настроить его на любую высоту родительского элемента. В настоящее время я пытаюсь настроить его как для одной, так и для двух строк текста.
Комментарии:
1. это хороший вопрос, потому что, зная, что элемент :before не является элементом dom, поэтому к нему не может быть доступа с помощью js (чтобы установить границы bottom и top = height div / 2). также добавление тега стиля прагматично работает только для одного div (в случае нескольких div с одним и тем же классом …)
Ответ №1:
Вот решение с использованием clip-path
. Идея состоит в том, чтобы использовать значения % в полигоне, чтобы показывать только необходимую форму, и это всегда будет работать независимо от высоты:
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
bottom: 0;
width: 25px;
right: -25px;
background: red;
-webkit-clip-path: polygon(100% 50%, 0 0, 0 100%);
clip-path: polygon(100% 50%, 0 0, 0 100%);
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
Вот еще одно решение, которое использует оба псевдоэлемента и некоторое косое преобразование для создания стрелки. Вы заметите, что этот элемент сохранит соотношение стрелки.
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
height: 50%;
width: 50%;
right: -25px;
background: red;
transform: skewX(20deg) translateX(-33%);
transform-origin: top;
z-index: -1;
}
.one-line:before {
content: '';
display: block;
position: absolute;
bottom: 0;
height: 50%;
width: 50%;
right: -25px;
background: red;
transform: skewX(-20deg) translateX(-33%);
transform-origin: bottom;
z-index: -1;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
Другой способ только с одним псевдоэлементом и linear-gradient
.
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
height: 100%;
width: 50px;
right: -50px;
background:
linear-gradient(to bottom left, transparent 49.4%, red 50%) top,
linear-gradient(to top left, transparent 49.4%, red 50%) bottom;
background-size:100% 50.2%;
background-repeat:no-repeat;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
И, наконец, без какого-либо псевдоэлемента и только фона на главном элементе:
.one-line {
font-size: 2em;
width: 200px;
padding-left:50px;
min-height: 50px;
height: auto;
background:
linear-gradient(blue,blue) left/calc(100% - 50px) 100%,
linear-gradient(to bottom left, transparent 49.4%, red 50%) top right/50px 50.2%,
linear-gradient(to top left, transparent 49.4%, red 50%) bottom right/50px 50.2%;
background-repeat:no-repeat;
margin: 5px;
position: relative;
color: #fff;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
Комментарии:
1. спасибо за ответ @Temani, ты всегда помогаешь. Я буду искать совместимость с браузером.
2. добро пожаловать @bhansa 😉 кстати, я думаю, вы обнаружите проблему только с IE, как обычно 🙂
3. @bhansa я добавил другое решение, которое должно быть более поддерживаемым 🙂
Ответ №2:
Ну, вы могли бы сохранить стрелку того же размера и выровнять ее по середине, изменив top на top: 50%;
и добавив transform: translateY(-50%);
.one-line{
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after{
content: '';
display: block;
position: absolute;
left: 100%;
width: 0;
height: 0;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
border-left: 25px solid red;
top: 50%;
transform: translateY(-50%);
}
<div class="one-line">text<br>text<br>text<br>text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text</div>
Комментарии:
1. спасибо за ваш ответ, я имею это в виду. Я все еще пытаюсь добиться упомянутого поведения. Хотя только для двух строк текста.
Ответ №3:
используя путь svg в качестве background-image
, вы могли бы расширить background-size
свойство до 100% 100%
. Просто убедитесь, что svg имеет preserveAspectRatio="none"
.one-line:after {
background-image: url('data:image/svg xml;charset=UTF-8,<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" preserveAspectRatio="none" viewBox="0 0 25.1 50" style="enable-background:new 0 0 25.1 50;" xml:space="preserve"><polygon class="st0" points="0,50 0,50 25,25 0,0" fill="#ff0000"/></svg>');
position: absolute;
top: 0;
left:100%;
height: 100%;
width: 25px;
background-size: 100% 100%;
background-repeat:no-repeat;
display: block;
content:'';
}
Комментарии:
1. это должно быть
background-repeat
вместо повторения. Кстати, отличное решение2. спасибо, что указали на это. Отредактировал мой ответ с вашим исправлением