SO-21094865
by David Thomas
HTML
<form action="#" method="post">
<fieldset>
<legend>Does your browser support..?</legend>
<label>
<span>Enter a selector to test</span>
<input type="text" id="testSelector">
</label>
<button type="button">Check your browser</button>
</fieldset>
<ul id="results"></ul>
</form>
CSS
*, ::before,::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
form {
margin-block: 1em;
margin-inline: auto;
width: clamp(30rem, 60vw, 1000px);
}
fieldset {
display: grid;
gap: 1em;
grid-auto-rows: min-content;
grid-template-columns: repeat(4, 1fr);
padding-block: 0.25em;
padding-inline: 0.5em;
}
label {
display: flex;
flex-flow: row nowrap;
gap: 1em;
grid-column: 1 / -1;
margin-block: 1em;
margin-inline: 0.5em;
padding: 0.25em;
}
label span {
align-self: center;
}
label span::after {
content: ': ';
}
label input {
flex-grow: 1;
object-fit: cover;
padding: 0.25em;
}
button {
grid-column: -2 / span 2;
}
#results li {
border-block-end-width: 3px;
border-block-end-style: solid;
font-family: monospace;
font-size: 1.5em;
padding-block: 0.25em;
padding-inline: 0.5em;
}
.supported {
border-block-end-color: lime;
}
.supported::marker {
content: '\2713';
}
.unsupported {
border-block-end-color: red;
}
.unsupported::marker {
content: '\2717';
}
JavaScript
// some DOM utilities and helpers,
// caching document as I don't enjoy typing that much:
const D = document,
// aliasing document.querySelector() and element.querySelector()
// again, because I don't enjoy typing; here the function takes
// two arguments 'sel' and 'context',
// 'sel' is a String, and is the selector for the element we're
// trying to retrieve;
// 'context' is the element/node we wish to search within; if
// no context is passed we default to document.querySelector()
// otherwise we use Element.querySelector():
get = (sel, context = D) => context.querySelector(sel),
// as above, except it's an alias for querySelectorAll(), and
// here we return an Array of nodes instead of a NodeList in
// order to use Array methods when/if required:
getAll = (sel, context = D) => [...context.querySelectorAll(sel)],
// alias for document.createElement(), which also allows properties
// to be set on the created element:
create = (tag, prop) => document.createElement(tag),
// simple function to allow for more elaborate templates, and
// arguments if required later:
templatedResult = (text) => `<code>${text}</code>`,
// named function to assess whether the browser supports/implements
// a given selector; this takes a reference to the Event Object
// passed automatically from EventTarget.addEventListener():
verifySelectorCompatibility = (evt) => {
// preventing default actions (as one of the events to which
// bind the function is form.submit):
evt.preventDefault();
// gathering variables/data
// here we retrieve the first/only <input> element within
// the document::
const input = get('#testSelector'),
// we retrieve the value from the <input> and trim that
// value of it's leading/trailing white-space:
selector = input.value.trim(),
// we retrieve the element with id=results:
output = get('#results'),
// we use the CSS.supports() function to assess...