table {
counter-reset: row-counter;
border-collapse: collapse;
width: 50%;
}
th,
td {
border: 1px solid #ddd;
text-align: center;
}
tbody tr {
counter-increment: row-counter;
}
tbody tr::before {
content: counter(row-counter);
display: table-cell;
border: 1px solid #ddd;
text-align: center;
}
<table>
<thead>
<tr>
<th>NO</th>
<th>ITEM</th>
<th>PRICE</th>
</tr>
</thead>
<tbody>
<tr>
<td>Banana</td>
<td>$2</td>
</tr>
<tr>
<td>Orange</td>
<td>$1</td>
</tr>
</tbody>
</table>
The counter-reset initializes the row counter at the beginning of the table.
Each <tr> in the <tbody> increments the counter using counter-increment.
The ::before pseudo-element is applied to each <tr> within the <tbody>.
The display: table-cell ensures that the generated row number behaves like a proper <td> element.
The content: counter(row-counter) displays the count
For simple understanding think row-counter as a variable. we declare when it initializes the table class.
table {
counter-reset: row-counter;
}
we want to increment the row-counter value for every tr in the table body
tbody tr {
counter-increment: row-counter;
}
we want to display the count
tbody tr::before {
content: counter(row-counter);
}
for more details you can refer https://www.w3schools.com/css/css_counters.asp