JSFiddle - React, Tailwind, and code Playground
by JohnJ
HTML
<div id="container" class="valign">
<div id="sc">some text</div>
<div id="subcontainer">
</div>
<div id="sc2">some text</div>
</div>
<div id="debug"></div>
CSS
#container {
width: 100px;
background-color: red;
height: 200px;
vertical-align: middle;
}
#subcontainer {
width: 50px;
background-color: green;
height: 50px;
margin: 0 auto;
}
#sc2 {
width: 50px;
background-color: blue;
margin: 50px auto 0;
color: white;
}
#sc {
width: 10px;
background-color: yellow;
float: left;
height: 80px;
}
JavaScript
// * another version of vertical_align
function log(mes) {
$('#debug').append(mes + '<br />');
}
function calc_height($elems) {
var height = 0;
$elems.each(function (index, el) {
height += $(el).outerHeight(true);
});
return height;
}
$('.valign').each(function (index, element) {
var $el = $(element),
$children = $el.children(':visible'),
height = $el.height(),
elems_height = 0,
top = 1,
valign = $el.css('vertical-align').toLowerCase(),
floats = {left: $(), none: $(), right: $()};
$children.each(function (index, child) {
var float = $(child).css('float');
float = (float == 'right' || float == 'left') ? float : 'none';
floats[float] = floats[float].add(child);
});
for (i in floats) {
if (floats[i].length == 0) continue;
elems_height = calc_height(floats[i]);
var $first_child = floats[i].first();
if (valign == 'middle') {
top = (height - elems_height) / 2;
} else if (valign == 'bottom') {
top = (height - elems_height);
}
if (top <= 0) continue;
var margin_collapse = $el.css('position') != 'absolute' && parseInt($el.css('borderTopWidth'), 10) == 0 && parseInt($el.css('paddingTop'), 10) == 0 && $el.css('float').toLowerCase() == 'none' && $el.css('display').toLowerCase() == 'block' && $el[0].nodeName.toLowerCase() != 'body';
// margin-top has effect of collapse, to see it, uncomment next string
// margin_collapse = false; // uncomment this string
if (margin_collapse) {
top -= 1;
$el.css({paddingTop: '1px', height: height - 1}); // create a condition for cancel the collapse. it can be replaced on $parent.css('position', 'absolute'); // , but this is worse in the general case
}
$first_child.css('marginTop', top);
...