Developed a custom jQuery plugin that enhances a specified <textarea>
element by adding a subtle grayed out selection when the element is not in focus.
// Created a jQuery plugin to enhance visibility of textarea selection when unfocused.
// This is achieved by overlaying the selected text with <mark> tags within an underlay
$.fn.selectionShadow = function () {
const $input = this
const prop = n => parseInt($input.css(n))
const $wrap = $input.wrap('<div>').parent() // wrapper
.css({
...Object.fromEntries(
'display width height font background resize margin overflowWrap'
.split(' ').map(x => [x, $input.css(x)])),
position: 'relative',
overflow: 'hidden',
border: 0,
padding: ['top', 'right', 'bottom', 'left'].map(
x => prop(`padding-${x}`) + prop(`border-${x}-width`) + 'px'
).join(' '),
})
const $shadow = $('<span>').prependTo($wrap) // shadow-selection
.css({ color: 'transparent' })
$input // input element
.on('focusin', () => $shadow.hide()) // hide shadow if focused
.on('focusout', () => $shadow.show())
.on('select', evt => { // if selection change
const i = evt.target // update shadow
const [x, s, a] = [i.value ?? '', i.selectionStart, i.selectionEnd]
$shadow.html(x.slice(0, s) + '<mark class=selectionShadow>' +
x.slice(s, a) + '</mark>' + x.slice(a))
})
.css({
boxSizing: 'border-box',
position: 'absolute', top: 0, left: 0, bottom: 0, right: 0,
overflow: 'hidden',
display: 'block',
background: 'transparent',
resize: 'none',
margin: 0,
})
$('head').append(
`<style>mark.selectionShadow { background: #0003; color: transparent }`)
}
To activate the plugin, use $('textarea').selectionShadow()
.
The plugin adds an 'underlay' layer to the textarea and ensures it matches the padding, font style, and word wrapping settings. This way, the textarea and underlay text align perfectly. The underlay updates alongside the textarea's selection, highlighting the current selection using <mark>
tags with a gray background (text color set to transparent
to avoid interference with text edges).
This implementation was crafted for personal web projects, feel free to utilize!