diff options
5 files changed, 113 insertions, 4 deletions
diff --git a/src/css/layout.nim b/src/css/layout.nim index 6869ae21..7d76e704 100644 --- a/src/css/layout.nim +++ b/src/css/layout.nim @@ -1011,16 +1011,18 @@ const CvalSizeMap = [dtHorizontal: cptWidth, dtVertical: cptHeight] proc resolveAbsoluteWidth(sizes: var ResolvedSizes; size: Size; positioned: RelativeRect; computed: CSSValues; lctx: LayoutContext) = + let padding = sizes.padding[dtHorizontal].sum() if computed{"width"}.u == clAuto: let u = max(size.w - positioned[dtHorizontal].sum(), 0) if computed{"left"}.u != clAuto and computed{"right"}.u != clAuto: # Both left and right are known, so we can calculate the width. - sizes.space.w = stretch(u) + # Well, but subtract padding first. + sizes.space.w = stretch(u - padding) else: # Return shrink to fit and solve for left/right. - sizes.space.w = fitContent(u) + # Well, but subtract padding first. + sizes.space.w = fitContent(u - padding) else: - let padding = sizes.padding[dtHorizontal].sum() let sizepx = computed{"width"}.spx(stretch(size.w), computed, padding) sizes.space.w = stretch(sizepx) @@ -1031,7 +1033,8 @@ proc resolveAbsoluteHeight(sizes: var ResolvedSizes; size: Size; let u = max(size.w - positioned[dtVertical].sum(), 0) if computed{"top"}.u != clAuto and computed{"bottom"}.u != clAuto: # Both top and bottom are known, so we can calculate the height. - sizes.space.h = stretch(u) + # Well, but subtract padding first. + sizes.space.h = stretch(u - sizes.padding[dtVertical].sum()) else: # The height is based on the content. sizes.space.h = maxContent() @@ -1053,6 +1056,9 @@ proc resolveAbsoluteSizes(lctx: LayoutContext; size: Size; ) sizes.resolveAbsoluteWidth(size, positioned, computed, lctx) sizes.resolveAbsoluteHeight(size, positioned, computed, lctx) + # Subtract margins. + for dim, it in sizes.space.mpairs: + it.u = max(it.u - sizes.margin[dim].sum(), 0) return sizes # Calculate and resolve available width & height for floating boxes. @@ -1318,6 +1324,12 @@ proc popPositioned(lctx: LayoutContext; overflow: var Overflow; size: Size) = let child = it.child lctx.pushPositioned() var positioned: RelativeRect + var size = size + #TODO this is very ugly. + # I'm subtracting the X offset because it's normally equivalent to + # the float-induced offset. But this isn't always true, e.g. it + # definitely isn't in flex layout. + size.w -= it.offset.x var sizes = lctx.resolveAbsoluteSizes(size, positioned, child.computed) var marginBottom = lctx.layoutRootBlock(child, it.offset, sizes) if sizes.space.w.t == scFitContent and child.state.intr.w > size.w: diff --git a/test/layout/position-absolute-float-subtracted-from-available-space.color.expected b/test/layout/position-absolute-float-subtracted-from-available-space.color.expected new file mode 100644 index 00000000..120e6324 --- /dev/null +++ b/test/layout/position-absolute-float-subtracted-from-available-space.color.expected @@ -0,0 +1,6 @@ +[48;2;255;0;0masdf [48;2;128;0;128mtest test test [49m +[48;2;128;0;128m test test test [49m +[48;2;128;0;128m test test test [49m +[48;2;128;0;128m test test test [49m +[48;2;128;0;128m test test [49m + diff --git a/test/layout/position-absolute-float-subtracted-from-available-space.html b/test/layout/position-absolute-float-subtracted-from-available-space.html new file mode 100644 index 00000000..2bb24b83 --- /dev/null +++ b/test/layout/position-absolute-float-subtracted-from-available-space.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<body> +<div style="position: relative; width: 30ch; height: 5em; background: purple"> +<div style="display: inline-block; float: left; width: 50%; background: red"> +asdf +</div> +<div style="display: inline-block; float: left; position: absolute"> +test test test test test test test test test test test test test test diff --git a/test/layout/position-absolute-margin-padding-subtracted-from-available-space.color.expected b/test/layout/position-absolute-margin-padding-subtracted-from-available-space.color.expected new file mode 100644 index 00000000..9500e73f --- /dev/null +++ b/test/layout/position-absolute-margin-padding-subtracted-from-available-space.color.expected @@ -0,0 +1,41 @@ +[48;2;128;0;128m [48;2;255;0;0mtest [49m +[48;2;128;0;128m [48;2;255;0;0mtest [49m +[48;2;128;0;128m [48;2;255;0;0mtest [49m +[48;2;128;0;128m [48;2;255;0;0mtest [49m +[48;2;128;0;128m [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;128;0;128m [49m +[48;2;255;0;0m test [49mtest +[48;2;255;0;0m test [49mtest +[48;2;255;0;0m [49m +[48;2;255;0;0m [49m +[48;2;255;0;0m [49m +[48;2;255;0;0m test [49mtest +[48;2;255;0;0m test [49mtest +[48;2;255;0;0m [49m +[48;2;255;0;0m [49m +[48;2;255;0;0m [49m +[48;2;128;0;128m [48;2;255;0;0mtest [49m +[48;2;128;0;128m [48;2;255;0;0mtest [49m +[48;2;128;0;128m [48;2;255;0;0mtest [49m +[48;2;128;0;128m [48;2;255;0;0mtest [49m +[48;2;128;0;128m [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;128;0;128m [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m test [49m +[48;2;255;0;0m [49m + diff --git a/test/layout/position-absolute-margin-padding-subtracted-from-available-space.html b/test/layout/position-absolute-margin-padding-subtracted-from-available-space.html new file mode 100644 index 00000000..35a256df --- /dev/null +++ b/test/layout/position-absolute-margin-padding-subtracted-from-available-space.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<div style="position: relative; width: 10ch; height: 5em; background: purple"> +<div style="margin-left: 5ch; position: absolute; background: red"> +test test test test +</div> +</div> +<div style="position: relative; width: 10ch; height: 5em; background: purple; box-sizing: border-box"> +<div style="padding-left: 5ch; width: 10ch; position: absolute; box-sizing: border-box; background: red"> +test test test test +</div> +</div> +<div style="position: relative; width: 10ch; height: 5em; background: red"> +<div style="padding-left: 5ch; width: 10ch; position: absolute"> +test test test test +</div> +</div> +<div style="position: relative; width: 10ch; height: 5em; background: red"> +<div style="left: 5ch; width: 10ch; position: absolute"> +test test test test +</div> +</div> + +<div style="position: relative; width: 10ch; height: 5em; background: purple"> +<div style="margin-left: 5ch; position: absolute; background: red"> +test test test test +</div> +</div> +<div style="position: relative; width: 10ch; height: 5em; background: purple; box-sizing: border-box"> +<div style="padding-left: 5ch; position: absolute; box-sizing: border-box; background: red"> +test test test test +</div> +</div> +<div style="position: relative; width: 10ch; height: 5em; background: red"> +<div style="padding-left: 5ch; position: absolute"> +test test test test +</div> +</div> +<div style="position: relative; width: 10ch; height: 5em; background: red"> +<div style="left: 5ch; position: absolute"> +test test test test +</div> +</div> |