Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Badge isn't a perfect triangle

Tags:

html

css

I wrote a code to create a triangular badge. It is almost working, only lower end is kinda cut off.

Here is my code:

span {
  border: 1px solid #999;
  border-radius: 5px;
  display: inline-block;
  padding: 3px 8px;
  text-decoration: none;
}

.newBadge {
  border-right: 50px solid transparent !important;
  border-top: 50px solid #777 !important;
  height: 41px !important;
  left: 0px;
  position: absolute;
  top: 0px;
}

.badgeText {
  color: #fff;
  height: 90px;
  left: 0;
  position: absolute;
  top: 0;
  width: 100px;
  height: 90px;
}

.badgeText strong {
  display: block;
  height: 100%;
  left: 37px;
  position: relative;
  -webkit-transform: rotate(-45deg) translate(0, -25%);
  -moz-transform: rotate(-45deg) translate(0, -25%);
  -ms-transform: rotate(-45deg) translate(0, -25%);
  -o-transform: rotate(-45deg) translate(0, -25%);
  transform: rotate(-45deg) translate(0px, -25%);
  width: 100%;
  font-size: 12px;
  bottom: 10px;
}  
<span class="newBadge"></span>
<span class="badgeText">
  <strong>Text</strong>
</span>  

How do I fix the lower end of the triangle?

like image 642
Ajay Kulkarni Avatar asked Mar 11 '23 09:03

Ajay Kulkarni


2 Answers

I had to tweak .newBadge a little:

span {
  border: 1px solid #999;
  border-radius: 5px;
  display: inline-block;
  padding: 3px 8px;
  text-decoration: none;


}

.newBadge {
  border-right: 80px solid transparent !important;
  border-top: 70px solid #777 !important;
  height: 41px !important;
  left: -20px;
  position: absolute;
  top: 0px;
  border-bottom:none;
}

.badgeText {
  color: #fff;
  height: 90px;
  left: 0;
  position: absolute;
  top: 0;
  width: 100px;
  height: 90px;
}

.badgeText strong {
  display: block;
  height: 100%;
  left: 37px;
  position: relative;
  -webkit-transform: rotate(-45deg) translate(0, -25%);
  -moz-transform: rotate(-45deg) translate(0, -25%);
  -ms-transform: rotate(-45deg) translate(0, -25%);
  -o-transform: rotate(-45deg) translate(0, -25%);
  transform: rotate(-45deg) translate(0px, -25%);
  width: 100%;
  font-size: 12px;
  bottom:10px;
}  
<span class="newBadge"></span>
<span class="badgeText">
  <strong>Text</strong>
</span>  

So, moving to the left side, little more, and increasing borders, did the trick, it seems? Also, border-bottom is set to none, because it is inherited from span...

Also, not sure, but if you can work with fixed dimensions of badge, i would suggest much easier (cleaner) HTML/CSS: https://jsfiddle.net/9o00a553/

div {
  border: 1px solid #999;
  border-radius: 5px;
  display: inline-block;
  padding: 3px 8px;
  text-decoration: none;
  width:100px;
  height:100px;
  position:relative;
overflow:hidden;
  margin:50px;
}
div:before {
  content:"";
  color:white;
  transform: rotate(-45deg);
  position:absolute;
  background:red;
  width:100%;
  height:100%;

 
  left:-50%;
  top:-50%;
}
span {
   transform: rotate(-45deg);
   color:white;
   position:absolute;
   z-index:3;
  left:12px;
   top:20px;
}
<div>
<span class="text">text</span>
</div>  
like image 146
sinisake Avatar answered Mar 23 '23 22:03

sinisake


Short answer: Remove the height and padding on the badge, and use the left and bottom borders as well. The changed style for .newBadge will be like this:

.newBadge {
  padding: 0;
  border-top: 33px solid #777 !important;
  border-bottom: 33px solid transparent !important;
  border-left: 33px solid #777 !important;
  border-right: 33px solid transparent !important;
  height: 0 !important;
  left: 0px;
  position: absolute;
  top: 0px;
}

On (very) close inspection, you might notice that the right and bottom corners look a little cut-off; this is due to the border-radius. Setting border-top-right-radius and border-bottom-left-radius to 0 will make those nice and sharp.

Longer answer: The cut-off on the bottom corner is being caused mainly by the padding, and also a little bit from the browser rendering something due to the border-radius and the transparent border color (I couldn't tell you why that is). I don't think there's a clean and reliable way to completely get rid of those artifacts.

Instead, rearrange the parts of the border to more directly create the triangle you want. Since the two legs are the top and left, color the top and left parts of the border, then use the opposite sides uncolored to square it up. Setting all the border-widths the same will keep it even. The width of each border will be half of the side length — since the original border width was 50, and the left and right padding were each 8, the new border width is (50 + 8 + 8) / 2 == 33.

The snippet shows a comparison of the original and changed results. Change the colors of each border fragment to see what each one contributes.

span {
  border: 1px solid #999;
  border-radius: 5px;
  display: inline-block;
  padding: 3px 8px;
  text-decoration: none;
}

.newBadge {
  border-right: 50px solid transparent !important;
  border-top: 50px solid #777 !important;
  height: 41px !important;
  left: 0px;
  position: absolute;
  top: 0px;
}

#new .newBadge {
  /* padding and height should be 0, or they will interfere with the triangle */
  padding: 0;
  height: 0 !important;
  /* Since the triangle is top and left, color those parts of the border, and use the opposite sides uncolored with the same dimensions to make the triangle perfect */
  border-top: 33px solid #777 !important;
  border-bottom: 33px solid transparent !important;
  border-left: 33px solid #777 !important;
  border-right: 33px solid transparent !important;
}

.badgeText {
  color: #fff;
  height: 90px;
  left: 0;
  position: absolute;
  top: 0;
  width: 100px;
  height: 90px;
}

.badgeText strong {
  display: block;
  height: 100%;
  left: 37px;
  position: relative;
  -webkit-transform: rotate(-45deg) translate(0, -25%);
  -moz-transform: rotate(-45deg) translate(0, -25%);
  -ms-transform: rotate(-45deg) translate(0, -25%);
  -o-transform: rotate(-45deg) translate(0, -25%);
  transform: rotate(-45deg) translate(0px, -25%);
  width: 100%;
  font-size: 12px;
  bottom: 10px;
}

/* The rest is just to get the side-by-side divs for comparison. */
div {
  position: relative;
  width: 140px;
  float: left;
  margin-top: 1.2em;
}
div::before {
  display: block;
  position: relative;
  top: -1.2em;
}
#old::before {
  content: "Old:";
}
#new::before {
  content: "New:";
}
<div id="old">
  <span class="newBadge"></span>
  <span class="badgeText">
    <strong>Text</strong>
  </span>
</div>
<div id="new">
  <span class="newBadge"></span>
  <span class="badgeText">
    <strong>Text</strong>
  </span>
</div>
like image 45
Reinstate Monica -- notmaynard Avatar answered Mar 23 '23 21:03

Reinstate Monica -- notmaynard