isCssContainingBlock()
Checks whether the specified DOM element is a CSS containing block for descendants of a certain position
.
/*
Checks whether a DOM Elementcan be the containing block for an element whose positioning is given by `position` (one of `static`, `relative`, `sticky`, `absolute`, `fixed`) and returns the reason why that's the case.
*/
function isCssContainingBlock(el, position = 'static') {
const s = getComputedStyle(el);
if (['static', 'relative', 'sticky'].includes(position)) {
return ['block', 'inline-block', 'list-item', 'grid', 'inline-grid', 'flex', 'inline-flex', 'table', 'inline-table', 'flow-root'].includes(s.display) ? `display: ${s.display}` : false;
}
if (position === 'absolute' && s.position !== 'static') {
return `position: ${s.position}`;
}
/* Code below applies to position: absolute, static */
if (s.transform !== 'none') {
return `transform: ${s.transform}`;
}
if (s.perspective !== 'none') {
return `perspective: ${s.perspective}`;
}
const wc = s.willChange.split(',').map(it => it.trim());
const wck = ['transform', 'perspective', 'filter'].find(k => wc.includes(k));
if (wck) {
return `will-change: ${wck}`;
}
if (s.filter !== 'none') {
return `filter: ${s.filter}`;
}
if (CSS.supports('contain', 'none')) {
if (s.contain.match(/\bpaint\b/)) {
return `contain: paint`;
}
}
if (s.backdropFilter !== 'none') {
return `backdrop-filter: ${s.backdropFilter}`;
}
return false;
}