- let r = 9;

svg(aria-hidden='true' width='0' height='0')
	filter#blob(color-interpolation-filters='sRGB' 
							y='-100%' height='300%')
		// extract highlight out of red channel and paint it blue
		feColorMatrix(values=`0 0 0 0 .12 
		                      0 0 0 0 .53 
													0 0 0 0 .9 
													1 0 0 0 0`)
		// blur the highlight - this does two things:
		// 1. makes edge pixels semitranparent
		// 2. rounds corners
		feGaussianBlur(stdDeviation=r)
		// slighly shrink it horizontally 
		// so we'd have a bit of a gap between the highlights 
		// if every single nav item was highlighted
		feMorphology(radius='4 0')
		// push alpha of most semitransparent pixels to either 0 or 1
		// save for a few pixels with alphas close to .5
		// this ives us a blob with smooth edges
		feComponentTransfer(result='baseblob')
			feFuncA(type='table' tableValues=[-r, r + 1].join(' '))
		
		// extract text & paint it differently based on 
		// whether it's hovered (on the green channel)
		// or not (on the blue channel)
		feColorMatrix(in='SourceGraphic' 
		              values=`0 .12 .27 0 0
									        0 .53 .32 0 0
													0 .89 .39 0 0 
													0 1   1   0 0` result='basetext')
		// intersect this text with the blob obtained before
		feComposite(in='baseblob' operator='in')
		// paint this intersection white
		feColorMatrix(values=`0 0 0 0 1 
		                      0 0 0 0 1 
													0 0 0 0 1 
													0 0 0 1 0`)
		// put the blob underneath it
		feBlend(in2='baseblob')
		// and the initial text underneath all else
		feBlend(in2='basetext')

nav(style='--k: 0')
	a(href='#' style='--i: 0' data-ico='🏠') home
	a(href='#' style='--i: 1' data-ico='📖') about
	a(href='#' style='--i: 2' data-ico='🗨️') contact
	a(href='#' style='--i: 3' data-ico='🌟') store
View Compiled
@import url('https://fonts.googleapis.com/css2?family=Inter&display=swap');

@property --k {
	syntax: '<number>';
	initial-value: 0;
	inherits: true
}

html, body { display: grid }

html { min-height: 100% }

body { background: #040404 }

svg[aria-hidden='true'] { position: fixed }

nav, a { display: flex }

nav {
	place-self: center;
	filter: url(#blob);
	transition: --k .35s cubic-bezier(.32, 1, .68, 1)
}

a {
	--sgn: clamp(-1, var(--i) - var(--k), 1);
	--bit: round(.5*(1 + var(--sgn)));
	--out: max(-1*var(--sgn), var(--sgn));
	--sel: calc(1 - var(--out));
	--col: #00f;
	gap: .375rem;
	position: relative;
	padding: 0 1.25rem;
	background: #000;
	color: var(--col);
	font: 1.125em/ 2.25 inter, sans-serif;
	text-decoration: none;
	text-transform: capitalize;
	isolation: isolate;
	
	&::before {
		background: var(--col) text;
		color: #0000;
		content: attr(data-ico)
	}
	
	&::after {
		--r: calc(var(--out)*var(--bit)*100%);
		--l: calc(var(--out)*(1 - var(--bit))*100%);
		position: absolute;
		inset: 1px 0;
		background: #f00;
		mix-blend-mode: lighten;
		clip-path: inset(0 var(--r) 0 var(--l));
		content: ''
	}
	
	&:hover, &:focus { --col: #0f0 }
	&:focus { outline: none }
	
	@supports (scale: Abs(-5)) { --out: abs(var(--sgn)) }
}
View Compiled
addEventListener('click', e => {
	let _t = e.target;
	
	if(_t.href) {
		_t.parentNode.style.setProperty('--k', +_t.style.getPropertyValue('--i'))
	}
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.