<section>
<span class="text-ring"></span>
</section>
:root {
--gray-0: #f8f9fa;
--gray-1: #f1f3f5;
--gray-2: #e9ecef;
--gray-3: #dee2e6;
--gray-4: #ced4da;
--gray-5: #adb5bd;
--gray-6: #868e96;
--gray-7: #495057;
--gray-8: #343a40;
--gray-9: #212529;
--gray-10: #16191d;
--gray-11: #0d0f12;
--gray-12: #030507;
/* Surfaces */
--text-1: var(--gray-12);
--text-2: var(--gray-10);
--text-3: var(--gray-8);
--text-4: var(--gray-7);
--surface-1: var(--gray-0);
--surface-2: var(--gray-1);
--surface-3: var(--gray-2);
--surface-4: var(--gray-3);
}
@media (prefers-color-scheme: dark) {
:root {
--text-1: var(--gray-1);
--text-2: var(--gray-3);
--text-3: var(--gray-5);
--text-4: var(--gray-6);
--surface-1: var(--gray-10);
--surface-2: var(--gray-9);
--surface-3: var(--gray-8);
--surface-4: var(--gray-7);
}
}
*,
*:after,
*:before {
box-sizing: border-box;
}
body {
display: grid;
place-items: center;
min-height: 100vh;
font-family: 'Google Sans', sans-serif, system-ui;
overflow: hidden;
background: var(--surface-3);
color: var(--text-2);
}
.text-ring {
position: relative;
}
.text-ring [style*=--index] {
font-weight: bold;
font-family: monospace;
text-transform: uppercase;
font-size: calc(var(--font-size, 2) * 1rem);
position: absolute;
top: 50%;
left: 50%;
transform:
translate(-50%, -50%)
rotate(calc(360deg / var(--total) * var(--index)))
translateY(calc(var(--radius, 5) * -1ch));
}
.dg :is(.cr.string, .cr.number) input[type=text] {
color: white;
line-height: 1;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
import { GUI } from "https://cdn.skypack.dev/dat.gui@0.7.9"
const RING = document.querySelector('.text-ring')
const OPTIONS = {
text: 'Your text here! • ',
size: 2,
radius: 5,
}
const CTRL = new GUI()
const onUpdate = () => {
RING.innerHTML = ''
const CHARS = OPTIONS.text.split('')
RING.style.setProperty('--total', CHARS.length)
RING.style.setProperty('--radius', OPTIONS.radius)
RING.style.setProperty('--font-size', OPTIONS.size)
const HIDDEN_CHARS = Object.assign(document.createElement('span'), {
ariaHidden: true,
})
for (let c = 0; c < CHARS.length; c++) {
HIDDEN_CHARS.innerHTML += `<span style="--index: ${c}">${CHARS[c]}</span>`
}
RING.appendChild(HIDDEN_CHARS)
RING.innerHTML += `<span class="sr-only">${OPTIONS.text}</span>`
}
CTRL.add(OPTIONS, 'text').name('Text').onChange(onUpdate)
CTRL.add(OPTIONS, 'size', 1, 10, 0.1).name('Font size (rem)').onChange(onUpdate)
CTRL.add(OPTIONS, 'radius', 1, 10, 0.1).name('Radius (ch)').onChange(onUpdate)
onUpdate()
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.