How to create a Numbering marker in CSS?

Viewed 145

I tried to write CSS code style to produce the numbering marker that look like this

Outcome of numbering marker

But it does not look correctly the right shape of the trailing circle.

Here I've tried with CSS code:

.comment-icon {
  width: 30px;
  height: 30px;
  border-radius: 100%;
  border: 2.45px solid #e7ad56;
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
}

.comment-icon:before {
  position: absolute;
  content: "";
  width: 15px;
  height: 16px;
  border-top: 2.45px solid #e7ad56;
  top: 20px;
  left: -6px;
  transform: rotate(286deg);
}

.comment-icon:after {
  position: absolute;
  content: "";
  width: 15px;
  height: 16px;
  border-bottom: 2.45px solid #e7ad56;
  top: 16px;
  left: -13px;
  transform: rotate(325deg);
}
<div class="comment-icon">1</div>

I have tried adjust :before and :after border positioning but did not get the right point at all.

Could anybody help get this shape please? Thanks.

2 Answers

You can use :before and :after selectors to create an arrow and adjust the position on it.

.comment-icon {
  width: 30px;
  height: 30px;
  border-radius: 100%;
  border: 2.45px solid #e7ad56;
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
}

.comment-icon:before {
  position: absolute;
  content: ""; 
  top: 24px;
  left: -9px;  
  width: 0; 
  height: 0; 
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;  
  border-top: 15px solid #e7ad56;
  transform: rotate(50deg);
}

.comment-icon:after {
  position: absolute;
  content: ""; 
  top: 24px;
  left: -5px;  
  width: 0; 
  height: 0; 
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;  
  border-top: 12px solid #fff;
  transform: rotate(50deg);
}
<div class="comment-icon">1</div>

I would use a SVG with an arc in the path, as a background image and a flexible size

The benefit of this approach is

  • a consistent visual rendering if you zoom the page;
  • an auto-fit behaviour if the number starts to grow.

.number {
   box-sizing: border-box;

   display: inline-grid;
   place-content: center;
   margin: .25rem;

   /* flexible width with logical properties */
   inline-size: max-content;
   min-inline-size: 2.8rem;
   padding: 0 .75rem;

   /* keeps the aspect ratio */
   aspect-ratio: 1;
   
   color: #444;
   font-family: system-ui, Arial;
   
   /* SVG background */
   background-image:
      url('data:image/svg+xml;UTF-8, <svg xmlns="http://www.w3.org/2000/svg" viewBox="-1 -3 51 53"><path d="M4 35 A24 24 0 1 1 12 43L1 47z" fill="none" stroke="gold" stroke-width="3" /></svg>');
   background-repeat: no-repeat;
   background-position: center;
}

.number * {
   font-weight: normal; 
}


@supports (not (aspect-ratio: 1)) {
   /* if aspect-ratio is not supported then use 
    * padding-bottom in a ::before pseudoelement
    */
   .number *::before {
      content: "";
      display: inline-block;
      vertical-align: middle;
      padding-bottom: calc(100% + 1.5rem);
   }
}
<span class="number"><b>1</b></span>
<span class="number"><b>82</b></span>
<span class="number"><b>239</b></span>
<span class="number"><b>69.420</b></span>
<span class="number"><b>4.060.752</b></span>


and here is the code of the SVG

<svg xmlns="http://www.w3.org/2000/svg" viewBox="-1 -3 51 53">
   <path d="M4 35 A24 24 0 1 1 12 43L1 47z" 
         fill="none" stroke="gold" stroke-width="3"/>
</svg>

Note: as you may have noticed, the tickness of the stroke increases when the number inside the marker is really long.

If you want to always keep the same tickness just add vector-effect="non-scaling-stroke" in the SVG, like in the following example

.number {
   box-sizing: border-box;

   display: inline-grid;
   place-content: center;
   margin: .25rem;

   /* flexible width with logical properties */
   inline-size: max-content;
   min-inline-size: 2.8rem;
   padding: 0 .75rem;

   /* keeps the aspect ratio */
   aspect-ratio: 1;
   
   color: #444;
   font-family: system-ui, Arial;
   
   /* SVG background */
   background-image:
      url('data:image/svg+xml;UTF-8, <svg xmlns="http://www.w3.org/2000/svg" viewBox="-1 -3 51 53"><path d="M4 35 A24 24 0 1 1 12 43L1 47z" fill="none" stroke="gold" stroke-width="3" vector-effect="non-scaling-stroke" /></svg>');
   background-repeat: no-repeat;
   background-position: center;
}

.number * {
   font-weight: normal; 
}


@supports (not (aspect-ratio: 1)) {
   /* if aspect-ratio is not supported then use 
    * padding-bottom in a ::before pseudoelement
    */
   .number *::before {
      content: "";
      display: inline-block;
      vertical-align: middle;
      padding-bottom: calc(100% + 1.5rem);
   }
}
<span class="number"><b>1</b></span>
<span class="number"><b>82</b></span>
<span class="number"><b>239</b></span>
<span class="number"><b>69.420</b></span>
<span class="number"><b>4.060.752</b></span>

Tested on latest Chrome, Firefox and Safari.

Here's how it looks with a 500% zoom

enter image description here

Related