Squarespace missing labels on product pages
Recently I was asked to ensure that aa existing shop on Squarespace passed all the tests to pass the WCAG accessibility guidelines.
This required some detailed adjustments to many elements and adjustments to text and background colours to achieve the required 4.5:1 contrast ratio. However, the most challenging and surprising fix required a label to be added to the product pages. For some reason Squarespace had no way of adding an HTML label for the fields that enabled product options and quantities to be selected.
Below is some code I was able to add within the Squarespace design section that added these labels. The context here is that screen readers will expect fields to have these labels to allow them to describe what the field does on the a page.
Code breakdown
The guts of the code is present in the function which does the following:
- Create a variable assigned to the ”label_name’ field object
- Check if a field label with the ‘label_name’ exists
- If not then create a new label linked to the field with text passed to the function and with class ‘visuallyhidden’
- note: the visuallyhidden class is set elsewhere to hide the label. It will be hidden on screen but visible to the screen readers
<script>
document.addEventListener('DOMContentLoaded', function () {
add_labels('variant-option-Grade-select', 'Choose your grade');
add_labels('variant-option-Type-select', 'Choose a type');
add_labels('variant-option-Size-select', 'Choose a size');
add_labels('variant-option-Option-select', 'Choose an option');
add_labels('quantity-input', 'Select the quantity');
function add_labels(label_name, label_message) {
const field = document.querySelector('[name="' + label_name + '"]');
if (field) {
// Give the field an id so the label can reference it (if it doesn't have one already)
if (!field.id) {
field.id = label_name;
}
// Check if a label already exists for this field
const existingLabel = field.id
? document.querySelector(`label[for="${field.id}"]`)
: null;
// Also check for a wrapping label (e.g. <label><input>...</label>)
const wrappingLabel = field.closest('label');
if ((!existingLabel && !wrappingLabel)) {
const label = document.createElement('label');
label.setAttribute('for', field.id);
label.setAttribute('class', 'visuallyhidden');
label.textContent = label_message;
// Insert the label right before the field
field.parentNode.insertBefore(label, field);
}
else {
console.log("Label exists");
}
}
}
});
</script>
