Dynamically aligning :after according to parent height
I am trying to create an arrow label, using 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>I want the after element to take the same height which is of parent, how can I do this by either css or js?
Note: The text inside the label is dynamically populating. [Max length of text: 2 lines]
It might not be possible, as I am thinking, to adjust it any height of parent. Currently I am trying it to adjust for both one and two lines of text.
javascript jquery html css
add a comment |
I am trying to create an arrow label, using 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>I want the after element to take the same height which is of parent, how can I do this by either css or js?
Note: The text inside the label is dynamically populating. [Max length of text: 2 lines]
It might not be possible, as I am thinking, to adjust it any height of parent. Currently I am trying it to adjust for both one and two lines of text.
javascript jquery html css
1
this is a good question , because knowing that the :before element isn't a dom element , so can't be access by js ( in order to set border bottom and top = height of div /2 ) . also adding style tag pragmatically work only for one div (in case of multiple div with same class ...)
– Boo Berr'ita
Jan 16 at 20:59
add a comment |
I am trying to create an arrow label, using 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>I want the after element to take the same height which is of parent, how can I do this by either css or js?
Note: The text inside the label is dynamically populating. [Max length of text: 2 lines]
It might not be possible, as I am thinking, to adjust it any height of parent. Currently I am trying it to adjust for both one and two lines of text.
javascript jquery html css
I am trying to create an arrow label, using 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>I want the after element to take the same height which is of parent, how can I do this by either css or js?
Note: The text inside the label is dynamically populating. [Max length of text: 2 lines]
It might not be possible, as I am thinking, to adjust it any height of parent. Currently I am trying it to adjust for both one and two lines of text.
.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>.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>javascript jquery html css
javascript jquery html css
edited Jan 16 at 20:02
asked Jan 16 at 19:47
bhansa
4,54821328
4,54821328
1
this is a good question , because knowing that the :before element isn't a dom element , so can't be access by js ( in order to set border bottom and top = height of div /2 ) . also adding style tag pragmatically work only for one div (in case of multiple div with same class ...)
– Boo Berr'ita
Jan 16 at 20:59
add a comment |
1
this is a good question , because knowing that the :before element isn't a dom element , so can't be access by js ( in order to set border bottom and top = height of div /2 ) . also adding style tag pragmatically work only for one div (in case of multiple div with same class ...)
– Boo Berr'ita
Jan 16 at 20:59
1
1
this is a good question , because knowing that the :before element isn't a dom element , so can't be access by js ( in order to set border bottom and top = height of div /2 ) . also adding style tag pragmatically work only for one div (in case of multiple div with same class ...)
– Boo Berr'ita
Jan 16 at 20:59
this is a good question , because knowing that the :before element isn't a dom element , so can't be access by js ( in order to set border bottom and top = height of div /2 ) . also adding style tag pragmatically work only for one div (in case of multiple div with same class ...)
– Boo Berr'ita
Jan 16 at 20:59
add a comment |
3 Answers
3
active
oldest
votes
Here is a solution using clip-path. The idea is to use % values in the polygon to only show the needed shape and it will always work whatever the height is:
.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>Here is another solution that rely on both pseudo elements and some skew transformation to create the arrow. You will notice that this one will keep ratio of the arrow.
.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>Another way with only one pseudo element and 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 50%, red 50.5%) top/100% 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom/100% 50%;
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>And finally without any pseudo element and only background on the main element:
.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 50%, red 50.5%) top right/50px 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom right/50px 50%;
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
thanks for the answer @Temani, you are always a help. I'll look for browser compatibility.
– bhansa
Jan 17 at 6:02
1
@bhansa welcome ;) by the way i guess you will only find issue with IE as usual :)
– Temani Afif
Jan 17 at 7:50
@bhansa i added another solution that should be more supported :)
– Temani Afif
Jan 17 at 8:47
2
good trick , & well explained !
– Boo Berr'ita
Jan 17 at 17:39
add a comment |
Well, you could opt to keep the arrow the same size and align it in the middle by changing top to top: 50%; and adding 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>
thanks for your answer, I have that in mind. I am still trying to achieve the mentioned behavior. Though just for upto two lines of text.
– bhansa
Jan 16 at 19:53
add a comment |
using an svg path as a background-image, you could stretch the background-size property to 100% 100%. Just make sure the svg has 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:'';
}
https://jsfiddle.net/7jm54u6L/
1
it should bebackground-repeatinstead of repeat. By the way great solution
– Temani Afif
Jan 16 at 20:52
thanks for pointing that out. Edited my response with your fix
– Adam Coulombe
Jan 16 at 21:19
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f48288765%2fdynamically-aligning-after-according-to-parent-height%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here is a solution using clip-path. The idea is to use % values in the polygon to only show the needed shape and it will always work whatever the height is:
.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>Here is another solution that rely on both pseudo elements and some skew transformation to create the arrow. You will notice that this one will keep ratio of the arrow.
.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>Another way with only one pseudo element and 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 50%, red 50.5%) top/100% 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom/100% 50%;
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>And finally without any pseudo element and only background on the main element:
.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 50%, red 50.5%) top right/50px 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom right/50px 50%;
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
thanks for the answer @Temani, you are always a help. I'll look for browser compatibility.
– bhansa
Jan 17 at 6:02
1
@bhansa welcome ;) by the way i guess you will only find issue with IE as usual :)
– Temani Afif
Jan 17 at 7:50
@bhansa i added another solution that should be more supported :)
– Temani Afif
Jan 17 at 8:47
2
good trick , & well explained !
– Boo Berr'ita
Jan 17 at 17:39
add a comment |
Here is a solution using clip-path. The idea is to use % values in the polygon to only show the needed shape and it will always work whatever the height is:
.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>Here is another solution that rely on both pseudo elements and some skew transformation to create the arrow. You will notice that this one will keep ratio of the arrow.
.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>Another way with only one pseudo element and 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 50%, red 50.5%) top/100% 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom/100% 50%;
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>And finally without any pseudo element and only background on the main element:
.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 50%, red 50.5%) top right/50px 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom right/50px 50%;
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
thanks for the answer @Temani, you are always a help. I'll look for browser compatibility.
– bhansa
Jan 17 at 6:02
1
@bhansa welcome ;) by the way i guess you will only find issue with IE as usual :)
– Temani Afif
Jan 17 at 7:50
@bhansa i added another solution that should be more supported :)
– Temani Afif
Jan 17 at 8:47
2
good trick , & well explained !
– Boo Berr'ita
Jan 17 at 17:39
add a comment |
Here is a solution using clip-path. The idea is to use % values in the polygon to only show the needed shape and it will always work whatever the height is:
.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>Here is another solution that rely on both pseudo elements and some skew transformation to create the arrow. You will notice that this one will keep ratio of the arrow.
.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>Another way with only one pseudo element and 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 50%, red 50.5%) top/100% 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom/100% 50%;
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>And finally without any pseudo element and only background on the main element:
.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 50%, red 50.5%) top right/50px 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom right/50px 50%;
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>Here is a solution using clip-path. The idea is to use % values in the polygon to only show the needed shape and it will always work whatever the height is:
.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>Here is another solution that rely on both pseudo elements and some skew transformation to create the arrow. You will notice that this one will keep ratio of the arrow.
.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>Another way with only one pseudo element and 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 50%, red 50.5%) top/100% 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom/100% 50%;
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>And finally without any pseudo element and only background on the main element:
.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 50%, red 50.5%) top right/50px 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom right/50px 50%;
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>.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;
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>.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>.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 50%, red 50.5%) top/100% 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom/100% 50%;
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: 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 50%, red 50.5%) top/100% 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom/100% 50%;
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 50%, red 50.5%) top right/50px 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom right/50px 50%;
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>.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 50%, red 50.5%) top right/50px 50.5%,
linear-gradient(to top left, transparent 50%, red 50.5%) bottom right/50px 50%;
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>edited Nov 12 at 15:37
answered Jan 16 at 20:20
Temani Afif
64.4k93675
64.4k93675
1
thanks for the answer @Temani, you are always a help. I'll look for browser compatibility.
– bhansa
Jan 17 at 6:02
1
@bhansa welcome ;) by the way i guess you will only find issue with IE as usual :)
– Temani Afif
Jan 17 at 7:50
@bhansa i added another solution that should be more supported :)
– Temani Afif
Jan 17 at 8:47
2
good trick , & well explained !
– Boo Berr'ita
Jan 17 at 17:39
add a comment |
1
thanks for the answer @Temani, you are always a help. I'll look for browser compatibility.
– bhansa
Jan 17 at 6:02
1
@bhansa welcome ;) by the way i guess you will only find issue with IE as usual :)
– Temani Afif
Jan 17 at 7:50
@bhansa i added another solution that should be more supported :)
– Temani Afif
Jan 17 at 8:47
2
good trick , & well explained !
– Boo Berr'ita
Jan 17 at 17:39
1
1
thanks for the answer @Temani, you are always a help. I'll look for browser compatibility.
– bhansa
Jan 17 at 6:02
thanks for the answer @Temani, you are always a help. I'll look for browser compatibility.
– bhansa
Jan 17 at 6:02
1
1
@bhansa welcome ;) by the way i guess you will only find issue with IE as usual :)
– Temani Afif
Jan 17 at 7:50
@bhansa welcome ;) by the way i guess you will only find issue with IE as usual :)
– Temani Afif
Jan 17 at 7:50
@bhansa i added another solution that should be more supported :)
– Temani Afif
Jan 17 at 8:47
@bhansa i added another solution that should be more supported :)
– Temani Afif
Jan 17 at 8:47
2
2
good trick , & well explained !
– Boo Berr'ita
Jan 17 at 17:39
good trick , & well explained !
– Boo Berr'ita
Jan 17 at 17:39
add a comment |
Well, you could opt to keep the arrow the same size and align it in the middle by changing top to top: 50%; and adding 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>
thanks for your answer, I have that in mind. I am still trying to achieve the mentioned behavior. Though just for upto two lines of text.
– bhansa
Jan 16 at 19:53
add a comment |
Well, you could opt to keep the arrow the same size and align it in the middle by changing top to top: 50%; and adding 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>
thanks for your answer, I have that in mind. I am still trying to achieve the mentioned behavior. Though just for upto two lines of text.
– bhansa
Jan 16 at 19:53
add a comment |
Well, you could opt to keep the arrow the same size and align it in the middle by changing top to top: 50%; and adding 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>Well, you could opt to keep the arrow the same size and align it in the middle by changing top to top: 50%; and adding 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>.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>.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>answered Jan 16 at 19:52
Kevin Jantzer
6,45521845
6,45521845
thanks for your answer, I have that in mind. I am still trying to achieve the mentioned behavior. Though just for upto two lines of text.
– bhansa
Jan 16 at 19:53
add a comment |
thanks for your answer, I have that in mind. I am still trying to achieve the mentioned behavior. Though just for upto two lines of text.
– bhansa
Jan 16 at 19:53
thanks for your answer, I have that in mind. I am still trying to achieve the mentioned behavior. Though just for upto two lines of text.
– bhansa
Jan 16 at 19:53
thanks for your answer, I have that in mind. I am still trying to achieve the mentioned behavior. Though just for upto two lines of text.
– bhansa
Jan 16 at 19:53
add a comment |
using an svg path as a background-image, you could stretch the background-size property to 100% 100%. Just make sure the svg has 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:'';
}
https://jsfiddle.net/7jm54u6L/
1
it should bebackground-repeatinstead of repeat. By the way great solution
– Temani Afif
Jan 16 at 20:52
thanks for pointing that out. Edited my response with your fix
– Adam Coulombe
Jan 16 at 21:19
add a comment |
using an svg path as a background-image, you could stretch the background-size property to 100% 100%. Just make sure the svg has 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:'';
}
https://jsfiddle.net/7jm54u6L/
1
it should bebackground-repeatinstead of repeat. By the way great solution
– Temani Afif
Jan 16 at 20:52
thanks for pointing that out. Edited my response with your fix
– Adam Coulombe
Jan 16 at 21:19
add a comment |
using an svg path as a background-image, you could stretch the background-size property to 100% 100%. Just make sure the svg has 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:'';
}
https://jsfiddle.net/7jm54u6L/
using an svg path as a background-image, you could stretch the background-size property to 100% 100%. Just make sure the svg has 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:'';
}
https://jsfiddle.net/7jm54u6L/
edited Jan 16 at 21:18
answered Jan 16 at 20:46
Adam Coulombe
982179
982179
1
it should bebackground-repeatinstead of repeat. By the way great solution
– Temani Afif
Jan 16 at 20:52
thanks for pointing that out. Edited my response with your fix
– Adam Coulombe
Jan 16 at 21:19
add a comment |
1
it should bebackground-repeatinstead of repeat. By the way great solution
– Temani Afif
Jan 16 at 20:52
thanks for pointing that out. Edited my response with your fix
– Adam Coulombe
Jan 16 at 21:19
1
1
it should be
background-repeat instead of repeat. By the way great solution– Temani Afif
Jan 16 at 20:52
it should be
background-repeat instead of repeat. By the way great solution– Temani Afif
Jan 16 at 20:52
thanks for pointing that out. Edited my response with your fix
– Adam Coulombe
Jan 16 at 21:19
thanks for pointing that out. Edited my response with your fix
– Adam Coulombe
Jan 16 at 21:19
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f48288765%2fdynamically-aligning-after-according-to-parent-height%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
this is a good question , because knowing that the :before element isn't a dom element , so can't be access by js ( in order to set border bottom and top = height of div /2 ) . also adding style tag pragmatically work only for one div (in case of multiple div with same class ...)
– Boo Berr'ita
Jan 16 at 20:59