- let rc = 1000;
- let cc = 1, ic = 0;
- let s = 2.25*rc, o = -.5*s;
- let min = 3, max = 9, p = min;
- let ba = 2*Math.PI/p;
- let cos = +(Math.cos(.5*ba)).toFixed(2);
- let rp = .003*rc, ms = 4*rp, mo = -.5*ms;
- let vx = [];

- for(let i = 0; i < p; i++)
	- let ca = i*ba;
	- vx.push([rc*Math.cos(ca), rc*Math.sin(ca)])

- vx = vx.map(c => c.map(k => +k.toFixed(1)).join(' ')).join(', ')

body(style=`--p: ${p}; --cc: ${cc}; --ic: ${ic}; --cos: ${cos}`)
	form
		.wrap.wrap--opt(role='group' aria-label='Group of checkboxes that control whether the polygon-related circles are shown or not.')
			input#cc(type='checkbox' checked=cc === 1)
			label.cc(for='cc') circumcircle
			input#ic(type='checkbox' checked=ic === 1)
			label.ic(for='ic') incircle
		.wrap.wrap--num(role='group' aria-label='Slider controlling the number of polygon vertices. In the no JS case, dragging its thumb cannot change anything, so the actual range input does not get diplayed, only the label and the initial output.' style=`--min: ${min}; --max: ${max}`)
			label(for='p') Number of polygon vertices
			input#p(type='range' min=min max=max value=p)
			output(for='p')

	svg(viewBox=[o, o, s, s].join(' ') style=`--sw: ${.01*rc}px`)
		marker#cm(viewBox=[mo, mo, ms, ms].join(' ') markerWidth=ms markerHeight=ms)
			circle.point.cc(r=rp)
		marker#im(viewBox=[mo, mo, ms, ms].join(' ') markerWidth=ms markerHeight=ms)
			circle.point.ic(r=rp)
		polygon(points=vx)
		circle.circ.cc(r=rc)
		circle.circ.ic(r=rc)
		- for(let i = 0; i < max; i++)
			line.rad.ic(x2=rc style=`--i: ${i}`)
			line.rad.cc(x2=rc style=`--i: ${i}`)
		circle.point.o(r=.015*rc)
View Compiled
$c0: #ff7a18, #af002d, #319197;
$c1: #00908a, #41024f, #f60c61, #ff6a00, #ffb231;
$cd: #170e27;
$cm: #434343;
$cl: #d4d4d4;

$track-p: Min(.5em, 2vw);
$track-u: 2.125em;
$track-h: .25em;
$track-r: .5*$track-h;

$thumb-d: 1em;
$thumb-r: .5*$thumb-d;

$arrow-a: 70deg;
$arrow-b: .25em;
$arrow-r: .25em;

$label-d: 3ch;
$label-o: -.5*$label-d;

$t: .3s;

@mixin track() {
	border: none;
	width: 100%; height: $track-h;
	border-radius: $track-r;
	background: 
		radial-gradient(circle at var(--pos), 
			transparent calc(var(--js)*(#{$thumb-r} - 2px)), 
			#ccc calc(var(--js)*(#{$thumb-r} - 1px)))
}

@mixin thumb($f: 0) {
	margin-top: $f*($track-r - $thumb-r);
	border: none;
	width: $thumb-d; height: $thumb-d;
	border-radius: 50%;
	background: currentcolor;
	filter: Invert(var(--not-focus)) brightness(calc(1 + .9*var(--not-focus)));
	transition: $t;
	transition-property: transform, filter;
	
	.js & { transform: scale(calc(.5*(1 + var(--focus)))) }
}

*, ::after {
	box-sizing: inherit;
	margin: 0;
	border: none;
	padding: 0;
	background: transparent;
	color: inherit;
	font: inherit;
}

html { 
	--k: var(--js, 0);
	--not-k: calc(1 - var(--k));
	
	&.js { --js: 1 }
}

body {
	--i: var(--narr, 1);
	--not-i: calc(1 - var(--i));
	--j: var(--wide, 1);
	--not-j: calc(1 - var(--j));
	--c: #{nth($c0, 1)};
	display: grid;
	overflow-x: hidden;
	grid-template-rows: max-content 1fr;
	height: 100vh;
	font: 400 clamp(.875em, 6.25vw, 1.5em)/ 1.375 raleway, sans-serif;
	
	@media (max-width: 745px) { --wide: 0 }
	@media (min-width: 400px) { --narr: 0 }
}

form {
	display: grid;
	grid-gap: $track-p;
	padding: $track-p;
	background: $cd;
	color: $cl
}

.wrap {
	padding: .25em $track-p;
	border-radius: 5px;
	box-shadow: 2px 2px #000;
	background: $cm;
	filter: grayScale(var(--not-focus));
	counter-reset: n var(--n);
	transition: filter $t;
	
	&--opt {
		display: flex;
		flex-wrap: wrap;
		justify-content: center
	}

	&--num {
		--focus: 0;
		--not-focus: calc(1 - var(--focus));
		--range: calc(var(--max) - var(--min));
		--track-w: clamp(4.5em, calc(100vw - 4*#{$track-p}), calc(var(--range)*#{$track-u}));
		--pos: calc(#{$thumb-r} + (var(--p) - var(--min))/var(--range)*(var(--track-w) - #{$thumb-d}));
		display: grid;
		place-content: center;
		counter-reset: p var(--p);
		
		label { margin: 0 calc(var(--js)*var(--j)*#{$track-p}) }
		
		&:focus-within { --focus: 1 }
	}
	
	> * { align-self: center }
}

input[type='checkbox'] {
	z-index: 2;
	width: $thumb-d; height: $thumb-d;
	opacity: 0;
	cursor: pointer;
	
	+ label {
		--focus: 0;
		--not-focus: calc(1 - var(--focus));
		display: flex;
		z-index: 1;
		align-items: center;
		margin: 0 $track-p 0 calc(-1*(#{$thumb-d} + #{$track-p}));
		padding: 0 $track-p;
		color: var(--c);
		filter: grayScale(var(--not-focus)) brightness(calc(1 + .5*var(--not-focus)));
		transition: filter $t;
		cursor: pointer;
		
		&::before {
			display: grid;
			place-content: center;
			margin: 0 $track-p 0 0;
			width: $thumb-d; height: $thumb-d;
			box-shadow: inset 0 0 0 2px var(--c);
			color: rgba(nth($c0, 1), var(--mc));
			content: '✔'
		}
	}
	
	&:focus + label { --focus: 1 }
}

input[type='range'] {
	&, &::-webkit-slider-thumb, 
	&::-webkit-slider-runnable-track {
		-webkit-appearance: none
	}
	
	display: var(--js, none);
	grid-area: 
		calc(1 + var(--not-j))/ 
		calc(1 + var(--j));
	width: var(--track-w); height: $thumb-d;
	color: var(--c);
	cursor: pointer;
	
	&::-webkit-slider-runnable-track { @include track() }
	
	&::-moz-range-track { @include track() }
	
	&::-webkit-slider-thumb { @include thumb(1) }
	
	&::-moz-range-thumb { @include thumb() }
	
	&:focus { outline: solid 0 transparent }
}

output {
	grid-area: 
		calc(1 + var(--i) + var(--not-j))/ 
		calc(1 + 2*var(--k)*var(--not-i) + var(--not-k));
	justify-self: start;
	margin: 
		calc(var(--js)*(var(--i)*#{$track-p} + var(--not-i)*#{-$arrow-b})) 
		0 
		calc(var(--js)*var(--not-i)*#{-$arrow-b}) 
		calc(var(--js)*var(--not-i)*#{$track-p});
	min-width: 2em;
	border-radius: $arrow-r;
	transform: translate(calc(var(--i)*(var(--pos) - 50%)));
	background: rgba(nth($c0, 1), var(--k));
	text-align: center;
	
	&::after { content: counter(p) }
	
	@supports (background: conic-gradient(red, tan)) {
		.js & {
			--xy: calc(var(--i)*50%) calc(var(--not-i)*50%);
			margin-top: calc(var(--not-i)*#{-$arrow-b} + var(--i)*#{$track-p});
			border: solid $arrow-b transparent;
			border-radius: $arrow-b + $arrow-r;
			--mask: 
				linear-gradient(red, red) padding-box, 
				conic-gradient(from calc(90deg - .5*#{$arrow-a} + var(--i)*90deg) at var(--xy), 
						red #{$arrow-a}, transparent 0%) 
					var(--xy)/ 50% 50% no-repeat border-box;
			-webkit-mask: var(--mask);
							mask: var(--mask);
		}
	}
}

svg {
	place-self: stretch;
	fill: none;
	stroke-width: var(--sw)
}

marker { overflow: visible }

.point {
	fill: var(--gc);
	stroke: $cd;
	stroke-width: calc(.625*var(--sw));
	
	marker & { stroke-width: calc(.1*var(--sw)) }
}

polygon {
	stroke: nth($c0, 1);
	stroke-linejoin: round
}

.ic {
	--mc: var(--ic);
	--mf: var(--cos);
	--gc: #{nth($c0, 3)}
}

.cc {
	--mc: var(--cc);
	--mf: 1;
	--gc: #{nth($c0, 2)}
}

.circ, .rad { stroke: var(--gc) }

.circ {
	opacity: var(--mc);
	
	&.ic {
		transform: scale(var(--cos));
		stroke-width: calc(var(--sw)/var(--cos));
	}
}

[id='im'] circle { transform: scalex(calc(1/var(--cos))) }

line {
	transform: 
		rotate(calc((var(--i) + var(--o, 0))/var(--p)*1turn)) 
		scalex(var(--mf));
	stroke-width: calc(.5*var(--sw));
	stroke-dasharray: calc(2*var(--sw));
	opacity: calc(var(--mc)*(var(--p) - var(--i)));
	marker-end: url(#cm);
	
	&.ic {
		--o: .5;
		marker-end: url(#im)
	}
}

.o {
	--gc: #{nth($c1, 5)};
	opacity: calc(var(--cc) + var(--ic))
}
View Compiled
document.documentElement.classList.add('js');

const _BODY = document.body, 
			_POLY = document.querySelector('polygon'), 
			RC = +document.querySelector('.circ.cc').getAttribute('r');

addEventListener('input', e => {
	let _t = e.target, typ = _t.type, val;
	
	switch(_t.type) {
		case 'checkbox':
			val = 1*_t.checked;
			break;
		case 'range':
			if(typ === 'range') {
				val = +_t.value;
				let ba = 2*Math.PI/val, vx = [];

				for(let i = 0; i < val; i++) {
					let ca = i*ba;
					vx.push([RC*Math.cos(ca), RC*Math.sin(ca)])
				}

				vx = vx.map(c => c.map(k => +k.toFixed(1)).join(' ')).join(', ');
				_POLY.setAttribute('points', vx);
				_BODY.style.setProperty('--cos', Math.cos(.5*ba))
			}
	}
	
	document.body.style.setProperty(`--${_t.id}`, val);
}, false);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.