JSFiddle - React, Tailwind, and code Playground
HTML
<div id="a">
<div id="aa">aa
<p id="aaa">aaa</p>
<span id="aab">aab</span>
<span id="aac" style="display:block;">aac</span>
</div>
<div id="ab" style="float: left;">ab</div>
<div id="ac" style="position: absolute;">ac
<div id="aca" style="float: left;">aca</div>
<div id="acb">acb</div>
</div>
<div id="ad" style="overflow: hidden;">ad
<p id="ada">ada</p>
<span id="adb">adb</span>
<span id="adc" style="display:block;">adc</span>
</div>
</div>
<div id="b" style="overflow: hidden;">
<div id="ba">ba
<p id="baa">baa</p>
<span id="bab">bab</span>
<span id="bac" style="display:block;">bac</span>
</div>
</div>
JavaScript
function isInFlow(elm, ctxRoot) {
ctxRoot = ctxRoot || document.body;
var $elm = $(elm),
ch = -1,
h;
if (!$elm.length) {
return false;
}
while ($elm[0] !== document.body) {
h = $elm.height();
if (h < ch || !okProps($elm)) {
return false;
}
ch = h;
$elm = $elm.parent();
if (!$elm.length) {
// not attached to the DOM
return false;
}
if ($elm[0] === ctxRoot) {
// encountered the ctxRoot and has been
// inflow the whole time
return true;
}
}
// should only get here if elm
// is not a child of ctxRoot
return false;
}
function okProps($elm) {
if ($elm.css('float') !== 'none'){
return false;
}
if ($elm.css('overflow') !== 'visible'){
return false;
}
switch ($elm.css('position')) {
case 'static':
case 'relative':
break;
default:
return false;
}
switch ($elm.css('display')) {
case 'block':
case 'list-item':
case 'table':
return true;
}
return false;
}
console.log('yes ',isInFlow('#a'));
console.log('yes ',isInFlow('#aa'));
console.log('yes ',isInFlow('#aaa'));
console.log('no ',isInFlow('#aab'));
console.log('yes ',isInFlow('#aac'));
console.log('no ',isInFlow('#ab'));
console.log('no ',isInFlow('#ac'));
console.log('no ',isInFlow('#aca'));
console.log('no ',isInFlow('#acb'));
console.log('no ',isInFlow('#aca'));
console.log('no ',isInFlow('#ad'));
console.log('no ',isInFlow('#ada'));
console.log('no ',isInFlow('#adb'));
console.log('no ',isInFlow('#adc'));
$('#aac').detach();
console.log('no ',isInFlow('#aac'));
$('#aa').detach();
console.log('no ',isInFlow('#aaa'));
var b = $('#b')[0];
console.log('no ',isInFlow(b));
console.log('no ...