chromium/third_party/blink/web_tests/css3/flexbox/position-absolute-child.html

<!DOCTYPE html>
<html>
<style>
body {
    margin: 0;
}

.title {
    margin-top: 1em;
}

.flexbox {
    display: flex;
    background-color: #aaa;
    position: relative;
}
.flexbox div {
    border: 0;
    flex: none;
}

.horizontal-tb {
    writing-mode: horizontal-tb;
}
.vertical-rl {
    writing-mode: vertical-rl;
}
.vertical-lr {
    writing-mode: vertical-lr;
}

.row {
    flex-flow: row;
}
.row-reverse {
    flex-flow: row-reverse;
}
.column {
    flex-flow: column;
}
.column-reverse {
    flex-flow: column-reverse;
}

.flexbox :nth-child(1) {
    background-color: blue;
}
.flexbox :nth-child(2) {
    background-color: green;
}
.flexbox :nth-child(3) {
    background-color: red;
}

.rtl {
    direction: rtl;
}
.ltr {
    direction: ltr;
}

</style>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../resources/check-layout-th.js"></script>
<body onload="checkLayout('.flexbox')">
<div id=log></div>

<script>
function getFlexDirection(flexFlow, writingMode)
{
    if (writingMode.indexOf('horizontal') != -1)
        return (flexFlow.indexOf('row') != -1) ? 'width' : 'height';
    return (flexFlow.indexOf('row') != -1) ? 'height' : 'width';
}

var writingModes = ['horizontal-tb', 'vertical-rl', 'vertical-lr'];
var flexFlows = ['row', 'column', 'row-reverse', 'column-reverse'];
var directions = ['ltr', 'rtl'];

// In each group, you have 3x3 tests. The first 3 test "regular" flexbox,
// the second test justify-content: space-between, and the final three test
// justify-content: center; align-items: center;
// In each of these groups, the absolute item is in position 0, 1, 2.
// crossAxisOffset is used for the absolute-positioned child.
var expectations = {
    'horizontal-tb': {
        row: {
            ltr: [
                { offsets: [0, 0, 240], sizes: [0, 240, 360] },
                { offsets: [0, 0, 150], sizes: [150, 0, 450] },
                { offsets: [0, 200, 0], sizes: [200, 400, 0] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 560, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [600, 360, 0], sizes: [0, 240, 360] },
                { offsets: [450, 600, 0], sizes: [150, 0, 450] },
                { offsets: [400, 0, 600], sizes: [200, 400, 0] },
                { offsets: [580, 560, 0] },
                { offsets: [560, 580, 0] },
                { offsets: [560, 0, 580] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
        },
        column: {
            ltr: [
                { offsets: [0, 0, 48], sizes: [0, 48, 72] },
                { offsets: [0, 0, 30], sizes: [30, 0, 90] },
                { offsets: [0, 40, 0], sizes: [40, 80, 0] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 80, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [0, 0, 48], sizes: [0, 48, 72] },
                { offsets: [0, 0, 30], sizes: [30, 0, 90] },
                { offsets: [0, 40, 0], sizes: [40, 80, 0] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 80, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
        },
        'row-reverse': {
            ltr: [
                { offsets: [600, 360, 0], sizes: [0, 240, 360] },
                { offsets: [450, 600, 0], sizes: [150, 0, 450] },
                { offsets: [400, 0, 600], sizes: [200, 400, 0] },
                { offsets: [580, 560, 0] },
                { offsets: [560, 580, 0] },
                { offsets: [560, 0, 580] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [0, 0, 240], sizes: [0, 240, 360] },
                { offsets: [0, 0, 150], sizes: [150, 0, 450] },
                { offsets: [0, 200, 0], sizes: [200, 400, 0] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 560, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
        },
        'column-reverse': {
            ltr: [
                { offsets: [120, 72, 0], sizes: [0, 48, 72] },
                { offsets: [90, 120, 0], sizes: [30, 0, 90] },
                { offsets: [80, 0, 120], sizes: [40, 80, 0] },
                { offsets: [100, 80, 0] },
                { offsets: [80, 100, 0] },
                { offsets: [80, 0, 100] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [120, 72, 0], sizes: [0, 48, 72] },
                { offsets: [90, 120, 0], sizes: [30, 0, 90] },
                { offsets: [80, 0, 120], sizes: [40, 80, 0] },
                { offsets: [100, 80, 0] },
                { offsets: [80, 100, 0] },
                { offsets: [80, 0, 100] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
        },
    },
    'vertical-rl': {
        row: {
            // The same as horizontal-tb + column.
            ltr: [
                { offsets: [0, 0, 48], sizes: [0, 48, 72] },
                { offsets: [0, 0, 30], sizes: [30, 0, 90] },
                { offsets: [0, 40, 0], sizes: [40, 80, 0] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 80, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [120, 72, 0], sizes: [0, 48, 72] },
                { offsets: [90, 120, 0], sizes: [30, 0, 90] },
                { offsets: [80, 0, 120], sizes: [40, 80, 0] },
                { offsets: [100, 80, 0] },
                { offsets: [80, 100, 0] },
                { offsets: [80, 0, 100] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
        },
        column: {
            // The same as horizontal-tb + row.
            ltr: [
                { offsets: [600, 360, 0], sizes: [0, 240, 360] },
                { offsets: [450, 600, 0], sizes: [150, 0, 450] },
                { offsets: [400, 0, 600], sizes: [200, 400, 0] },
                { offsets: [580, 560, 0] },
                { offsets: [560, 580, 0] },
                { offsets: [560, 0, 580] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [600, 360, 0], sizes: [0, 240, 360] },
                { offsets: [450, 600, 0], sizes: [150, 0, 450] },
                { offsets: [400, 0, 600], sizes: [200, 400, 0] },
                { offsets: [580, 560, 0] },
                { offsets: [560, 580, 0] },
                { offsets: [560, 0, 580] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
        },
        'row-reverse': {
            ltr: [
                { offsets: [120, 72, 0], sizes: [0, 48, 72] },
                { offsets: [90, 120, 0], sizes: [30, 0, 90] },
                { offsets: [80, 0, 120], sizes: [40, 80, 0] },
                { offsets: [100, 80, 0] },
                { offsets: [80, 100, 0] },
                { offsets: [80, 0, 100] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [0, 0, 48], sizes: [0, 48, 72] },
                { offsets: [0, 0, 30], sizes: [30, 0, 90] },
                { offsets: [0, 40, 0], sizes: [40, 80, 0] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 80, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
        },
        'column-reverse': {
            ltr: [
                { offsets: [0, 0, 240], sizes: [0, 240, 360] },
                { offsets: [0, 0, 150], sizes: [150, 0, 450] },
                { offsets: [0, 200, 0], sizes: [200, 400, 0] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 560, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [0, 0, 240], sizes: [0, 240, 360] },
                { offsets: [0, 0, 150], sizes: [150, 0, 450] },
                { offsets: [0, 200, 0], sizes: [200, 400, 0] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 560, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
        }
    },
    'vertical-lr': {
        row: {
            // The same as horizontal-tb + column.
            ltr: [
                { offsets: [0, 0, 48], sizes: [0, 48, 72] },
                { offsets: [0, 0, 30], sizes: [30, 0, 90] },
                { offsets: [0, 40, 0], sizes: [40, 80, 0] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 80, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [120, 72, 0], sizes: [0, 48, 72] },
                { offsets: [90, 120, 0], sizes: [30, 0, 90] },
                { offsets: [80, 0, 120], sizes: [40, 80, 0] },
                { offsets: [100, 80, 0] },
                { offsets: [80, 100, 0] },
                { offsets: [80, 0, 100] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
        },
        column: {
            ltr: [
                { offsets: [0, 0, 240], sizes: [0, 240, 360] },
                { offsets: [0, 0, 150], sizes: [150, 0, 450] },
                { offsets: [0, 200, 0], sizes: [200, 400, 0] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 560, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [0, 0, 240], sizes: [0, 240, 360] },
                { offsets: [0, 0, 150], sizes: [150, 0, 450] },
                { offsets: [0, 200, 0], sizes: [200, 400, 0] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 0, 560] },
                { offsets: [0, 560, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
        },
        'row-reverse': {
            ltr: [
                { offsets: [120, 72, 0], sizes: [0, 48, 72] },
                { offsets: [90, 120, 0], sizes: [30, 0, 90] },
                { offsets: [80, 0, 120], sizes: [40, 80, 0] },
                { offsets: [100, 80, 0] },
                { offsets: [80, 100, 0] },
                { offsets: [80, 0, 100] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [0, 0, 48], sizes: [0, 48, 72] },
                { offsets: [0, 0, 30], sizes: [30, 0, 90] },
                { offsets: [0, 40, 0], sizes: [40, 80, 0] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 0, 80] },
                { offsets: [0, 80, 0] },
                { offsets: [30, 10, 50], crossAxisOffset: 30 },
                { offsets: [10, 30, 50], crossAxisOffset: 30 },
                { offsets: [10, 50, 30], crossAxisOffset: 30 },
            ],
        },
        'column-reverse': {
            ltr: [
                { offsets: [600, 360, 0], sizes: [0, 240, 360] },
                { offsets: [450, 600, 0], sizes: [150, 0, 450] },
                { offsets: [400, 0, 600], sizes: [200, 400, 0] },
                { offsets: [580, 560, 0] },
                { offsets: [560, 580, 0] },
                { offsets: [560, 0, 580] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
            rtl: [
                { offsets: [600, 360, 0], sizes: [0, 240, 360] },
                { offsets: [450, 600, 0], sizes: [150, 0, 450] },
                { offsets: [400, 0, 600], sizes: [200, 400, 0] },
                { offsets: [580, 560, 0] },
                { offsets: [560, 580, 0] },
                { offsets: [560, 0, 580] },
                { offsets: [30, 50, 10], crossAxisOffset: 30 },
                { offsets: [50, 30, 10], crossAxisOffset: 30 },
                { offsets: [50, 10, 30], crossAxisOffset: 30 },
            ],
        },
    }
};

function setFlexboxSize(flexbox, flexDirection)
{
    if ('width' == flexDirection) {
        flexbox.style.width = '600px';
    } else {
        flexbox.style.width = '100px';
        flexbox.style.height = '120px';
    }
}

function addJustifyContentSpaceBetweenTests(writingMode, flexFlow, direction, flexDirection)
{
    var flexboxClassName = writingMode + ' ' + direction + ' ' + flexFlow;
    for (var absoluteIndex = 1; absoluteIndex <= 3; ++absoluteIndex) {
        var expected = expectations[writingMode][flexFlow][direction][2 + absoluteIndex];

        // Absolute div is 20px, other divs should be 40px.
        expected.sizes = [40, 40, 40];
        expected.sizes[absoluteIndex - 1] = 20;

        var flexbox = document.createElement('div');
        flexbox.className = 'flexbox ' + flexboxClassName;
        setFlexboxSize(flexbox, flexDirection);
        flexbox.style.justifyContent = 'space-between';
        for (var childIndex = 1; childIndex <= 3; ++childIndex) {
            var child = document.createElement('div');
            child.style[flexDirection] = '40px';
            if (absoluteIndex == childIndex) {
                child.style.position = 'absolute';
                child.style[flexDirection] = '20px';
                if ('height' == flexDirection)
                    child.style.width = '100px';
            }

            if ('width' == flexDirection)
                child.style.height = '20px';

            child.setAttribute('data-offset-' + (flexDirection == 'width' ? 'x' : 'y'), expected.offsets[childIndex - 1]);
            child.setAttribute('data-expected-' + flexDirection, expected.sizes[childIndex - 1]);
            flexbox.appendChild(child);
        }

        document.body.appendChild(flexbox);
    }
}

function addAlignItemsCenterTests(writingMode, flexFlow, direction, flexDirection)
{
    var flexboxClassName = writingMode + ' ' + direction + ' ' + flexFlow;
    for (var absoluteIndex = 1; absoluteIndex <= 3; ++absoluteIndex) {
        var expected = expectations[writingMode][flexFlow][direction][5 + absoluteIndex];

        var flexbox = document.createElement('div');
        flexbox.className = 'flexbox ' + flexboxClassName;
        flexbox.style.height = '100px';
        flexbox.style.width = '100px';
        flexbox.style.margin = "20px";
        flexbox.style.justifyContent = 'center';
        flexbox.style.alignItems = 'center';

        for (var childIndex = 1; childIndex <= 3; ++childIndex) {
            var child = document.createElement('div');
            if (absoluteIndex == childIndex) {
                child.style.position = 'absolute';
                child.style.outline = "2px solid yellow";
            }
            child.style.width = '40px';
            child.style.height = '40px';

            child.setAttribute('data-offset-' + (flexDirection == 'width' ? 'x' : 'y'), expected.offsets[childIndex - 1]);
            var expectedCrossAxisOffset = (absoluteIndex == childIndex) ? expected.crossAxisOffset : 30;
            child.setAttribute('data-offset-' + (flexDirection == 'width' ? 'y' : 'x'), expectedCrossAxisOffset);
            flexbox.appendChild(child);
        }

        document.body.appendChild(flexbox);
    }
}

writingModes.forEach(function(writingMode) {
    flexFlows.forEach(function(flexFlow) {
        directions.forEach(function(direction) {
            var flexboxClassName = writingMode + ' ' + direction + ' ' + flexFlow;
            var title = document.createElement('div');
            title.className = 'title';
            title.innerHTML = flexboxClassName;
            document.body.appendChild(title);

            var flexDirection = getFlexDirection(flexFlow, writingMode);
            for (var absoluteIndex = 1; absoluteIndex <= 3; ++absoluteIndex) {
                var expected = expectations[writingMode][flexFlow][direction][absoluteIndex - 1];

                var flexbox = document.createElement('div');
                flexbox.className = 'flexbox ' + flexboxClassName;
                setFlexboxSize(flexbox, flexDirection);
                for (var childIndex = 1; childIndex <= 3; ++childIndex) {
                    var child = document.createElement('div');
                    child.style.flex = childIndex;
                    if (childIndex == absoluteIndex)
                        child.style.position = 'absolute';

                    if ('width' == flexDirection)
                        child.style.height = '20px';

                    child.setAttribute('data-offset-' + (flexDirection == 'width' ? 'x' : 'y'), expected.offsets[childIndex - 1]);
                    child.setAttribute('data-expected-' + flexDirection, expected.sizes[childIndex - 1]);
                    flexbox.appendChild(child);
                }

                document.body.appendChild(flexbox);
            }
            addJustifyContentSpaceBetweenTests(writingMode, flexFlow, direction, flexDirection);
            addAlignItemsCenterTests(writingMode, flexFlow, direction, flexDirection);
        })
    })
})

</script>

</body>
</html>