Two pseudo elements ::before with different properties - html

Used two pseudo elements ::before with different border properties (see js fiddle). Despite "you can use only one ::before and one ::after pseudo element" this actualy worked. Why?
https://jsfiddle.net/8L7zou3e/1/
<div class="el"></div>
.el {
position: relative;
margin: 100px 0 0 500px;
width: 300px;
height: 100px;
background-color: #AA4343;
}
.el:before {
content: '';
display: inline-block;
width: 0;
height: 0;
border-top: 50px solid #e86d0a;
border-left: 50px solid transparent;
position: absolute;
top: 0;
left: -50px;
}
.el:before {
content: '';
display: inline-block;
width: 0;
height: 0;
border-bottom: 50px solid #e86d0a;
border-left: 50px solid transparent;
position: absolute;
top: 0px;
left: -50px;
}

You seem to have only one pseudo element.
And that's here in the UI:
Your CSS cascades to:
.el:before {
content: '';
display: inline-block;
width: 0;
height: 0;
border-top: 50px solid #e86d0a;
border-left: 50px solid transparent;
position: absolute;
border-bottom: 50px solid #e86d0a;
border-left: 50px solid transparent;
top: 0;
left: -50px;
}
See the way Chrome has treated your combined CSS:

There's only one pseudo-element but the properties are added because the two rules apply to that pseudo-element.
Your CSS is equivalent to
.el {
position: relative;
margin: 100px 0 0 500px;
width: 300px;
height: 100px;
background-color: #AA4343;
}
.el:before {
content: '';
display: inline-block;
width: 0;
height: 0;
border-top: 50px solid #e86d0a;
border-left: 50px solid transparent;
position: absolute;
border-bottom: 50px solid #e86d0a;
border-left: 50px solid transparent;
top: 0;
left: -50px;
}
It's similar to this case which probably is more obvious:
a {
color: red;
}
a {
font-weight: bold;
}

Related

How to make rectangle's border different?

HTML:
<div class="rectangle">Some text</div>
CSS:
.rectangle {
width: 300px;
height: 80px;
border: 5px solid red;
}
Is there any way to make div looks like in the photo?
You can use ::after and ::before to achieve the result.
.rectangle {
width: 300px;
height: 80px;
border: 5px solid red;
border-right: none;
position: relative;
}
/* for the triangular shape */
.rectangle::after {
content: "";
position: absolute;
right:-45px;
bottom: 0;
top:-5px;
width: 0;
height: 0;
border-left: 45px solid red;
border-top: 45px solid transparent;
border-bottom: 45px solid transparent;
z-index:1000;
}
/* for hiding the portion except the border
of the triangle shape */
.rectangle::before {
content: "";
position: absolute;
right:-40px;
bottom: 0;
top:0;
width: 0;
height: 0;
border-left: 40px solid white;
border-top: 40px solid transparent;
border-bottom: 40px solid transparent;
z-index:1001;
}
<div class="rectangle">Some text</div>
In case you don't need border like structure then you can avoid ::before portion and set background color to main div.
.rectangle {
width: 300px;
height: 80px;
border: 5px solid red;
border-right: none;
position: relative;
background:red;
}
.rectangle::after {
content: "";
position: absolute;
right:-45px;
bottom: 0;
top:-5px;
width: 0;
height: 0;
border-left: 45px solid red;
border-top: 45px solid transparent;
border-bottom: 45px solid transparent;
}
<div class="rectangle">Some text</div>
For more shapes refer : CSS Tricks
To keep only the border without filling the div, You can try using ::before and ::after.
Something like this:
.rectangle {
width: 200px;
height: 40px;
position: relative;
border-top: 2px solid red;
border-bottom: 2px solid red;
border-left: 2px solid red;
-moz-border-radius: 3px 0 0 3px;
-webkit-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
margin-left: 50px;
}
.rectangle::after {
content: "";
position: absolute;
left: 100%;
width: 0;
height: 0;
top: 2px;
border-top: 18px solid transparent;
border-left: 10px solid #fff;
border-bottom: 17px solid transparent;
}
.rectangle::before {
content: "";
position: absolute;
left: 100%;
width: 0;
top: -2px;
height: 0;
border-top: 22px solid transparent;
border-left: 14px solid red;
border-bottom: 22px solid transparent;
}
<div class="rectangle">Some text</div>
Consider rotating a pseudo-element by declaring a transform: rotate() property value, as demonstrated in the code snippet embedded below.
As an alternative to achieving the same behaviour declaring border property rules, this method allows borders to be declared on the element in an intuitive manner using only one pseudo-element.
Rotating an element in this way also gives you the option to fill in the element with a solid colour - allowing you more freedom in customization.
Code Snippet Demonstration:
.rectangle {
width: 300px;
height: 80px;
border: 5px solid red;
/* additional */
border-right: 0;
box-sizing: border-box;
position: relative; /* required */
}
/* Additional */
.rectangle:after {
content: "";
position: absolute;
width: 55px;
height: 55px;
border-right: 5px solid red;
border-top: 5px solid red;
box-sizing: inherit;
right: -28px;
top: 7px;
transform: rotate(45deg);
}
<div class="rectangle">Some text</div>
Check CSS Shapes
#pointer {
width: 200px;
height: 40px;
position: relative;
background: red;
}
#pointer:after {
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
border-left: 20px solid white;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
}
#pointer:before {
content: "";
position: absolute;
right: -20px;
bottom: 0;
width: 0;
height: 0;
border-left: 20px solid red;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
}
<div id="pointer">
</div>
you have to use the pseudo class after
.rectangle {
position: relative;
width:200px;
height:40px;
margin-left:40px;
color:#FFFFFF;
background-color:red;
text-align:center;
line-height:40px;
}
.rectangle:after {
content:"";
position: absolute;
left: 100%;
top:0px;
width:0px;
height:0px;
border-top:20px solid transparent;
border-left:40px solid red;
border-bottom:20px solid transparent;
}
<div class="rectangle">Some text</div>
You can do it using :before and :after
.rectangle {
width: 300px;
height: 80px;
border: 5px solid blue;
border-right: none;
position: relative;
}
.rectangle::before {
content: '';
border-top: 5px solid blue;
width: 120px;
position: absolute;
right: -115px;
bottom: 16px;
transform: rotate(-21deg);
}
.rectangle::after {
content: '';
border-top: 5px solid blue;
width: 120px;
position: absolute;
right: -115px;
top: 16px;
transform: rotate(21deg);
}
<div class="rectangle">Some text</div>

Border around a div with a triangle point at the bottom

Is there a way to achieve this border in CSS? I've got one DIV with list of bullet points and I need to wrap it in a border like the image.
You can first create one element with border except border-bottom and then use :before and :after pseudo-elements to add triangle border at bottom.
div {
width: 200px;
height: 150px;
border: 1px solid black;
border-bottom: none;
position: relative;
background: white;
margin: 20px;
}
div:after, div:before {
content: '';
width: 0;
height: 0;
border-style: solid;
border-width: 50px 101px 0 101px;
border-color: black transparent transparent transparent;
top: 100%;
left: -1px;
position: absolute;
}
div:after {
border-color: white transparent transparent transparent;
top: calc(100% - 1px);
}
<div></div>
Have a look at this Fiddle
Basically add this css to a div:
#base {
background: red;
display: inline-block;
height: 55px;
margin-left: 20px;
margin-top: 55px;
position: relative;
width: 100px;
}
#base:after {
border-bottom: 35px solid red;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
content: "";
height: 0;
left: 0;
position: absolute;
top: 54px;
width: 0;
-ms-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
try this one:
.down-arrow {
display: inline-block;
position: relative;
background: darkcyan;
padding: 15px 0;
width: 200px;
text-align: center;
}
.down-arrow:after {
content: '';
display: block;
position: absolute;
left: 0;
top: 100%;
width: 0;
height: 0;
border-top: 20px solid darkcyan;
border-right: 100px solid transparent;
border-bottom: 0 solid transparent;
border-left: 100px solid transparent;
}
DEMO HERE
Here is the code for the box:
.box {
background: #fff;
border: 1px solid #000;
display: inline-block;
height: 55px;
margin-left: 20px;
margin-top: 55px;
position: relative;
width: 100px;
}
.box:after {
border-top: 35px solid #fff;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
content: '';
height: 0;
left: 0;
position: absolute;
top: 55px;
width: 0;
}
.box:before {
border-top: 35px solid #000;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
content: '';
height: 0;
left: 0;
position: absolute;
top: 56px;
width: 0;
}
<div class="box">
</div>
I hope it helps

How to make this shape responsive? Changing values on borders does not work

I have found the following shape which I want to make responsive:
#hexagon {
width: 100px;
height: 55px;
background: red;
position: relative;
}
#hexagon:after {
content: "";
position: absolute;
bottom: -25px;
left: 0;
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 25px solid red;
}
<div id="hexagon">
If I'm changing the values of border-left, border-right or border-top in percentages, it doesn't work.

Combine Multiple Pseudo Elements into one HTML tag

I'm trying to create an element for ONE HTML tag that uses multiple pseudo elements/classes (eg. 4 or 5). Here is the end result I am trying to achieve, however I only want one HTML element:
.main {
position: relative;
display: inline-block;
padding: 5px;
background-color: pink;
border: 1px solid red;
}
.b1, .b2, .b3 {
display: inline-block;
}
.down-arrow-border {
position: absolute;
bottom: -15px;
left: 20px;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 15px solid red;
}
.down-arrow {
position: absolute;
bottom: -14px;
left: 21px;
width: 0;
height: 0;
border-left: 14px solid transparent;
border-right: 14px solid transparent;
border-top: 14px solid pink;
}
<div class="main">
<div class="b1">$</div>
<div class="b2">234</div>
<div class="b3">GBP</div>
<div class="down-arrow-border"></div>
<div class="down-arrow"></div>
</div>
Original Fiddle
Here is my attempt. I've only been able to use the ::before and ::after pseudo elements. How could I create the triangle element with additional pseudo elements/classes?
.b2 {
display: inline-block;
padding: 5px;
background-color: pink;
border: 1px solid red;
}
.b2::before{
content: '$';
}
.b2::after{
content: ' GBP';
}
<div class="b2">234</div>
Attemped Fiddle
Since there are more than two elements in your original (first fiddle), you cannot get this done with just one single element (because one element can at most have only two pseudo-elements attached to it).
The maximum reduction you can achieve is to do this using two elements like in the below snippet:
.main {
position: relative;
display: inline-block;
padding: 5px;
background-color: pink;
border: 1px solid red;
}
.b2 {
display: inline-block;
}
.b2::before {
content: '$';
}
.b2::after {
content: ' GBP';
}
.main::before {
position: absolute;
content: '';
bottom: -15px;
left: 20px;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 15px solid red;
}
.main::after {
position: absolute;
content: '';
bottom: -14px;
left: 21px;
width: 0;
height: 0;
border-left: 14px solid transparent;
border-right: 14px solid transparent;
border-top: 14px solid pink;
}
<div class="main">
<div class="b2">234</div>
</div>
But wait, that would definitely not be recommended solution. As Paulie_D had mentioned in his comments you are not using the pseudo-elements the appropriate way. Pseudo-elements should be used in general for adding extra styles to the element and not content that are critical (like a currency code, its symbol etc). They should be left to the back-end program which is fetching and sending the amount value.
So the solution that I would recommend would be the following:
.b2 {
position: relative;
display: inline-block;
padding: 5px;
background-color: pink;
border: 1px solid red;
}
.b2::before {
position: absolute;
content: '';
bottom: -15px;
left: 20px;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 15px solid red;
}
.b2::after {
position: absolute;
content: '';
bottom: -14px;
left: 21px;
width: 0;
height: 0;
border-left: 14px solid transparent;
border-right: 14px solid transparent;
border-top: 14px solid pink;
}
<div class="b2">$234 GBP</div>
If you are 100% intent on using pseudo-elements, I would give the below approach where the backend program sets data-curr-* attributes. But, it is way more easier for the backend to set the amount as a single string.
.main {
position: relative;
display: inline-block;
padding: 5px;
background-color: pink;
border: 1px solid red;
}
.b2 {
display: inline-block;
}
.b2::before {
content: attr(data-curr-symbol);
}
.b2::after {
content: ' ' attr(data-curr-code);
}
.main::before {
position: absolute;
content: '';
bottom: -15px;
left: 20px;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 15px solid red;
}
.main::after {
position: absolute;
content: '';
bottom: -14px;
left: 21px;
width: 0;
height: 0;
border-left: 14px solid transparent;
border-right: 14px solid transparent;
border-top: 14px solid pink;
}
<div class="main">
<div class="b2" data-curr-symbol="$" data-curr-code="GBP">234</div>
</div>

Issue to create hexagon using css

I am trying to create hexagon using image without set background image using css.
I tried below code where display perfect but its issue in email. Background image not set in email so need to remove from background and need to set any other way. I tried lots of different way to set but not succeed. As i am not designer so.
I used below code which done but not need to set any other way.
<div class="hexagon pic">
<span class="top"></span>
<span class="bottom"></span>
</div>
.hexagon {
background: url(http://placekitten.com/400/400/);
width: 400px;
height: 346px;
position: relative;
}
.hexagon span {
position: absolute;
display: block;
border-left: 100px solid red;
border-right: 100px solid red;
width: 200px;
}
.top {
top: 0;
border-bottom: 173px solid transparent;
}
.bottom {
bottom: 0;
border-top: 173px solid transparent;
}
Anyone have a idea.
Thanks
<div id="hexagon">
<img src="image.jpg">
</div>
//styles
#hexagon {
width: 100px;
height: 55px;
background: red;
position: relative;}
#hexagon:before {
content: "";
position: absolute;
top: -25px;
left: 0;
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 25px solid red;}
#hexagon:after {
content: "";
position: absolute;
bottom: -25px;
left: 0;
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 25px solid red;}
#hexagon > img { height: inherit; width: inherit; }
This will do the work.