I’m conflicted on whether I prefer this, or the default search engine loading in every new tab. That being said, here’s how to prevent your default search engine from loading every time you open new tabs in Google Chrome.
Continue readingFix Google reCaptcha’s “Missing form label” Accessibility Error
Chances are screen readers overlook Google’s faux pas when it comes to not providing labels for thier hidden g-recaptcha-response TEXTAREA, but we would prefer not seeing such errors during accessibility evaluations.
Here is a simple script to handle the problem gracefully.
Continue readingAdding pause/play button to Bootstrap carousel for better accessibility.
Starting with the example code for a carousel with indicators we add another button to the beginning of .carousel-indicators.
<button type="button" class="btn btn-sm" id="carouselExamplePause" aria-label="Pause">⏸︎</button>
Then we add JavaScript to make it functional.
Continue readingAutomatically adjust scroll-padding-top for “Skip to main content” links (useful for .sticky-top headers)
window.addEventListener('resize', () => {
document.documentElement.style.scrollPaddingTop = document.getElementById('content').getBoundingClientRect().top
})
Tip: Set default using CSS in case JavaScript is disabled.
html {
scroll-padding-top: 50px;
}
Toggle Bootstrap collapsible state by device screen size
How to turn on/off Bootstrap’s collapse function based on window.innerWidth
function toggleCollapsibility(container) {
// Default to disabled
let find = 'collapse', replace = 'collapse-disabled'
// We only want collapse on smaller devices
if (window.innerWidth < 992) {
// Flip to enabled
[find, replace] = [replace, find]
}
document.querySelectorAll(`${container} [data-bs-toggle="${find}"]`).forEach((element) => {
element.dataset.bsToggle = replace
})
}
Continue reading Helpful CSS Classes for Flipping and Rotating Elements
Useful CSS transformation classes for use with Content Security Policy (CSP).
/* Flip Horizontal */
.flip-h {
transform: scaleX(-1);
}
/* Flip Vertical */
.flip-v {
transform: scaleY(-1);
}
/* Rotation */
.rotate-0, .rotate-360 {
transform: rotate(0deg);
}
.rotate-45 {
transform: rotate(45deg);
}
.rotate-90 {
transform: rotate(90deg);
}
.rotate-135 {
transform: rotate(135deg);
}
.rotate-180 {
transform: rotate(180deg);
}
.rotate-225 {
transform: rotate(225deg);
}
.rotate-270 {
transform: rotate(270deg);
}
.rotate-315 {
transform: rotate(315deg);
}
Combining flip and rotate classes can achieve most desired display transformations.
Disable CodeIgniter 4 Cache Handler During Development
We recently ran into an issue where CodeIgniter’s cache() produced unexpected results during development. Our problem was forgetting to change the cache handler from ‘file’ to ‘dummy’ outside of the production environment. So we do not have to remember to change the handler, we modified our App’s Config\Cache::handler as follows…
public string $handler = (ENVIRONMENT === 'production') ? 'file' : 'dummy';
That one simple “set it and forget it” change could have saved wasted time spent debugging the problem.
Update: While discussing this with other developers, one alternative would be updating the .env file.
Hide Bootstrap 5 Tooltips When Clicked
Here’s an easy way to hide Bootstrap tooltips onclick. Useful for focusable elements that do not change the current document’s location.
document.querySelectorAll('[data-bs-toggle="tooltip"], .add-bs-tooltip').forEach(element => {
new bootstrap.Tooltip(element)
element.addEventListener('click', event => {
bootstrap.Tooltip.getInstance(event.currentTarget).hide()
})
})
Bonus: Our .add-bs-tooltip selector is for eliminating the need to wrap other Bootstrap elements that already have the data-bs-toggle attribute (modals, dropdowns, etc). 😉
Block Top-Level Domains (TLDs) Using cPanel Email Filters
Initially we had a long list of “From ends with” filters like below trying cut down on our most common spam sources.
From ends with .ru
From ends with .pk
From ends with .in
From ends with .de
From ends with .jp
From ends with .kr
Recently I noticed those rules were effectively blocking those TLDs. It did not take long to figure out why. Here are example FROM headers email systems might encounter.
From: "John Doe" <john@example.com>
From: Jane <jane@example.com>
From: bob@example.com
The problem with using “From ends with” is the header frequently ends with a greater-than symbol. So we decided to use “From matches regex” instead.
Continue readingAutomatically Adding Default Headers to ALL Fetch (AJAX) Requests
Below is an unobtrusive way to ensure AJAX headers are set with every fetch() request, which compliments our post regarding fetch() wrappers.
const originalFetch = fetch
fetch = ((url, options) => {
if (!options) options = {}
Object.assign(options, { headers: { 'X-Requested-With': 'XMLHttpRequest' } })
const promise = originalFetch(url, options).catch(error => { console.error(error) })
return promise
})
Now every fetch() request includes the X-Requested-With: XMLHttpRequest header.
We ultimately ended up with the following alternative to avoid replacing other existing headers.
Continue readingAdd PATTERN Support to TEXTAREA for Validation
While unfortunate, by now it should be well-known that textarea elements do not support pattern attributes. Why W3C would omit that attribute for multiline text fields is beyond me… maybe it’s because we cannot specify flags in our patterns? 🤔
Since we really wanted our textarea to validate by pattern, and until/if such support is added to the HTML standards, we modified a basic Bootstrap Validation script to make it work with minimal changes.
Continue readingHow to fix “Blocked aria-hidden on an element because its descendant retained focus.” in console
We regularly run into this Chrome console accessibility warning implementing Bootstrap Modals. There is supposed to be a fix coming in a future release of Bootstrap, but until then, we want to eliminate the warning. Our solution should be adaptable to other packages and components generating the same warning.
Continue readingBlocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users. Avoid using aria-hidden on a focused element or its ancestor. Consider using the inert attribute instead, which will also prevent focus. For more details, see the aria-hidden section of the WAI-ARIA specification at https://w3c.github.io/aria/#aria-hidden.
Element with focus: <button.btn-close>
Ancestor with aria-hidden: <div.modal fade#modal>