1

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

Harry
  • 87,580
  • 25
  • 202
  • 214
Bxx
  • 1,615
  • 1
  • 17
  • 30
  • 1
    Questions seeking code help must include the shortest code necessary to reproduce it **in the question itself**. Although you have provided a [**link to an example**](http://meta.stackoverflow.com/questions/254428/something-in-my-web-site-or-project-doesnt-work-can-i-just-paste-a-link-to-it), if the link were to become invalid, your question would be of no value to other future SO users with the same problem. – Paulie_D Mar 06 '16 at 22:09
  • At the moment any element only has two pseudo-elements and the way you are using them isn't appropriate. – Paulie_D Mar 06 '16 at 22:11
  • 1
    you may be able to look at this for help: [Speech bubble with arrow](http://stackoverflow.com/questions/30299093/speech-bubble-with-arrow) – jbutler483 Mar 07 '16 at 15:30

1 Answers1

2

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>
Harry
  • 87,580
  • 25
  • 202
  • 214