30 CSS Badges19 / 30

Pure CSSMIT licensed

Signal Bars

Four rectangles of increasing height — possibly the most iconic data visualization ever designed. Confidence, signal, relevance — whatever the product needs. Hover fills all bars to maximum.

Published

Live Demo
Try it

The code

<div class="bdg-19-stage">
  <div class="bdg-19-badge">
    <div class="bdg-19-bars-group">
      <div class="bdg-19-bar bdg-19-active"></div>
      <div class="bdg-19-bar bdg-19-active"></div>
      <div class="bdg-19-bar bdg-19-active"></div>
      <div class="bdg-19-bar bdg-19-active"></div>
    </div>
    <div class="bdg-19-info">
      <div class="bdg-19-strength">Excellent</div>
      <div class="bdg-19-label">Confidence · 4 / 4</div>
    </div>
  </div>

  <div class="bdg-19-mini-set">
    <div class="bdg-19-row-mini">
      <div class="bdg-19-bars-mini">
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
      </div>
      <div class="bdg-19-name-mini">Good · 3/4</div>
    </div>
    <div class="bdg-19-row-mini">
      <div class="bdg-19-bars-mini">
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
      </div>
      <div class="bdg-19-name-mini">Fair · 2/4</div>
    </div>
    <div class="bdg-19-row-mini">
      <div class="bdg-19-bars-mini">
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
      </div>
      <div class="bdg-19-name-mini">Weak · 1/4</div>
    </div>
  </div>
</div>
.bdg-19-stage {
  background: #f5f4f2;
  padding: 60px 48px;
  display: flex;
  flex-direction: column;
  gap: 36px;
  align-items: flex-start;
  width: 100%;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
}

.bdg-19-badge {
  display: inline-flex;
  align-items: flex-end;
  gap: 4px;
  padding: 16px 20px 14px;
  background: white;
  border: 1px solid #e0ddd8;
  box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  cursor: pointer;
  position: relative;
}

.bdg-19-badge:hover .bdg-19-bar {
  background: #1a1612 !important;
}

.bdg-19-bars-group {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  margin-right: 14px;
}

.bdg-19-bar {
  width: 8px;
  border-radius: 1px;
  transition: background 0.2s, height 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.bdg-19-bars-group .bdg-19-bar:nth-child(1) {
  height: 10px;
}

.bdg-19-bars-group .bdg-19-bar:nth-child(2) {
  height: 18px;
}

.bdg-19-bars-group .bdg-19-bar:nth-child(3) {
  height: 26px;
}

.bdg-19-bars-group .bdg-19-bar:nth-child(4) {
  height: 34px;
}

.bdg-19-active {
  background: #1a1612;
}

.bdg-19-inactive {
  background: #dddbd6;
}

.bdg-19-info {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 2px;
}

.bdg-19-strength {
  font-family: Georgia, "Fraunces", serif;
  font-size: 20px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.01em;
  color: #1a1612;
}

.bdg-19-label {
  font-family: system-ui, "Bricolage Grotesque", sans-serif;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #4a4239;
}

.bdg-19-mini-set {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0 4px;
}

.bdg-19-row-mini {
  display: flex;
  align-items: center;
  gap: 12px;
}

.bdg-19-bars-mini {
  display: flex;
  align-items: flex-end;
  gap: 2px;
}

.bdg-19-bars-mini .bdg-19-bar {
  width: 5px;
}

.bdg-19-bars-mini .bdg-19-bar:nth-child(1) {
  height: 6px;
}

.bdg-19-bars-mini .bdg-19-bar:nth-child(2) {
  height: 10px;
}

.bdg-19-bars-mini .bdg-19-bar:nth-child(3) {
  height: 14px;
}

.bdg-19-bars-mini .bdg-19-bar:nth-child(4) {
  height: 18px;
}

.bdg-19-name-mini {
  font-family: system-ui, "Bricolage Grotesque", sans-serif;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: #4a4239;
  text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .bdg-19-bar {
    transition: none;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Badge from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Signal Bars
Source: https://codefronts.com/snippets/css-badges/signal-bars/

Four rectangles of increasing height — possibly the most iconic data visualization ever designed. Confidence, signal, relevance — whatever the product needs. Hover fills all bars to maximum.
## HTML
```html
<div class="bdg-19-stage">
  <div class="bdg-19-badge">
    <div class="bdg-19-bars-group">
      <div class="bdg-19-bar bdg-19-active"></div>
      <div class="bdg-19-bar bdg-19-active"></div>
      <div class="bdg-19-bar bdg-19-active"></div>
      <div class="bdg-19-bar bdg-19-active"></div>
    </div>
    <div class="bdg-19-info">
      <div class="bdg-19-strength">Excellent</div>
      <div class="bdg-19-label">Confidence · 4 / 4</div>
    </div>
  </div>

  <div class="bdg-19-mini-set">
    <div class="bdg-19-row-mini">
      <div class="bdg-19-bars-mini">
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
      </div>
      <div class="bdg-19-name-mini">Good · 3/4</div>
    </div>
    <div class="bdg-19-row-mini">
      <div class="bdg-19-bars-mini">
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
      </div>
      <div class="bdg-19-name-mini">Fair · 2/4</div>
    </div>
    <div class="bdg-19-row-mini">
      <div class="bdg-19-bars-mini">
        <div class="bdg-19-bar bdg-19-active"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
        <div class="bdg-19-bar bdg-19-inactive"></div>
      </div>
      <div class="bdg-19-name-mini">Weak · 1/4</div>
    </div>
  </div>
</div>
```
## CSS
```css
.bdg-19-stage {
  background: #f5f4f2;
  padding: 60px 48px;
  display: flex;
  flex-direction: column;
  gap: 36px;
  align-items: flex-start;
  width: 100%;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
}

.bdg-19-badge {
  display: inline-flex;
  align-items: flex-end;
  gap: 4px;
  padding: 16px 20px 14px;
  background: white;
  border: 1px solid #e0ddd8;
  box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  cursor: pointer;
  position: relative;
}

.bdg-19-badge:hover .bdg-19-bar {
  background: #1a1612 !important;
}

.bdg-19-bars-group {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  margin-right: 14px;
}

.bdg-19-bar {
  width: 8px;
  border-radius: 1px;
  transition: background 0.2s, height 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.bdg-19-bars-group .bdg-19-bar:nth-child(1) {
  height: 10px;
}

.bdg-19-bars-group .bdg-19-bar:nth-child(2) {
  height: 18px;
}

.bdg-19-bars-group .bdg-19-bar:nth-child(3) {
  height: 26px;
}

.bdg-19-bars-group .bdg-19-bar:nth-child(4) {
  height: 34px;
}

.bdg-19-active {
  background: #1a1612;
}

.bdg-19-inactive {
  background: #dddbd6;
}

.bdg-19-info {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 2px;
}

.bdg-19-strength {
  font-family: Georgia, "Fraunces", serif;
  font-size: 20px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.01em;
  color: #1a1612;
}

.bdg-19-label {
  font-family: system-ui, "Bricolage Grotesque", sans-serif;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #4a4239;
}

.bdg-19-mini-set {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0 4px;
}

.bdg-19-row-mini {
  display: flex;
  align-items: center;
  gap: 12px;
}

.bdg-19-bars-mini {
  display: flex;
  align-items: flex-end;
  gap: 2px;
}

.bdg-19-bars-mini .bdg-19-bar {
  width: 5px;
}

.bdg-19-bars-mini .bdg-19-bar:nth-child(1) {
  height: 6px;
}

.bdg-19-bars-mini .bdg-19-bar:nth-child(2) {
  height: 10px;
}

.bdg-19-bars-mini .bdg-19-bar:nth-child(3) {
  height: 14px;
}

.bdg-19-bars-mini .bdg-19-bar:nth-child(4) {
  height: 18px;
}

.bdg-19-name-mini {
  font-family: system-ui, "Bricolage Grotesque", sans-serif;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: #4a4239;
  text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .bdg-19-bar {
    transition: none;
  }
}
```

How this works

A cellular / wifi signal-strength badge: 4-5 bars of ascending height, with the “active” number of bars coloured to indicate signal quality (5/5 full, 3/5 medium, 1/5 weak, 0/5 no signal). The pattern iOS, Android, macOS, Windows status bars ship.

Pure CSS. Bars are individual <span> elements sized via height:calc(var(--index) * 20% + 20%); the active count comes from a data-strength attribute that triggers CSS to colour only the first N bars.

Make it yours

  • Change strength via data-strength="0" through data-strength="5" on the wrapper.
  • Rebrand active vs inactive bar colours from --bar-on and --bar-off.
  • Adjust bar count (4 for iOS-style, 5 for Android-style).
  • Swap for wifi arcs (border-radius half-circles) for a wifi-icon variant.
  • Add a numeric readout of dBm (-50 to -100) for a technical display.

Gotchas — read before shipping

  • Signal-strength UIs are conventionally left-to-right ascending in Western contexts; in RTL locales, mirror the layout.
  • The 5-bar convention is arbitrary — real cellular signal is measured in dBm (a logarithmic scale); bars are a UX simplification.
  • For debug displays, pair the visual bars with the numeric dBm value.
  • Colour-only signal quality fails WCAG — the bar count is the accessible primary.

Browser support

ChromeSafariFirefoxEdge
45+9+16+45+

CSS attribute selectors, calc(), and custom properties are universally supported.

Techniques used in this demo

Search CodeFronts

Loading…