← All elements
<div class="notification">
<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="32" aria-hidden="true">
<path class="icon-off" stroke-linecap="round" stroke-linejoin="round" d="M9.143 17.082a24.248 24.248 0 0 0 3.844.148m-3.844-.148a23.856 23.856 0 0 1-5.455-1.31 8.964 8.964 0 0 0 2.3-5.542m3.155 6.852a3 3 0 0 0 5.667 1.97m1.965-2.277L21 21m-4.225-4.225a23.81 23.81 0 0 0 3.536-1.003A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6.53 6.53m10.245 10.245L6.53 6.53M3 3l3.53 3.53" />
<path class="icon-on" stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0" />
</svg>
<label for="switch">
<div class="label-text">
<span>
Notifications
<span class="off">Off</span>
<span class="on">On</span>
</span>
<span class="msg-off">Enjoy your day.</span>
<span class="msg-on">Spam on the way.</span>
</div>
</label>
<input type="checkbox" id="switch">
</div>About this button
A settings row with a bell icon, a status message and a switch. The :has() selector swaps the icon and text and makes the bell buzz when switched on.
How it works
A checkbox sits inside a grid row with a bell icon and two messages. The :has(input:checked) selector flips which icon and text are visible, so no extra classes are needed, and the bell plays a short buzz keyframe each time it is switched on. Custom properties and a cascade layer keep the styles tidy.
Ways to customise it
- Change the text in both message spans.
- Edit the buzz keyframe for a stronger shake.
- Replace the SVG paths with another icon.
Good to know
The control is a real checkbox with a label, so keyboard and screen reader users get it for free. :has() is supported in all current browsers.
Open an example, copy the HTML and the CSS, and paste them into your page. There is nothing to install and no JavaScript to load.