about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-04-14 19:41:07 +0200
committerbptato <nincsnevem662@gmail.com>2025-04-14 19:41:07 +0200
commitb7a918dba97ca723cef2d1b28ba1b11d10394169 (patch)
tree65494620d9c44a9b7e41fcd244e1dc2ef33104e6
parentfa4d825bb6c678653ddb675bd511d53a52df934f (diff)
downloadchawan-b7a918dba97ca723cef2d1b28ba1b11d10394169.tar.gz
render: fix positioning of absolutes with negative z-index
-rw-r--r--src/css/render.nim7
-rw-r--r--test/layout/absolute-negative-z-index-position-resolved-before-container.color.expected1
-rw-r--r--test/layout/absolute-negative-z-index-position-resolved-before-container.html4
3 files changed, 10 insertions, 2 deletions
diff --git a/src/css/render.nim b/src/css/render.nim
index 2687a1cd..7beda00c 100644
--- a/src/css/render.nim
+++ b/src/css/render.nim
@@ -489,14 +489,16 @@ proc resolveBlockOffset(box: CSSBox): Offset =
   var toPosition: seq[BlockBox] = @[]
   var it2 {.cursor.} = it
   var parent {.cursor.}: CSSBox = nil
+  var abs {.cursor.}: CSSBox = nil
   while it2 != nil:
+    if absolute and it2.positioned and abs == nil:
+      abs = it2 # record first absolute ancestor
     if it2.render.positioned and (not absolute or it2.positioned):
       break
     if it2 of BlockBox:
       toPosition.add(BlockBox(it2))
     it2 = it2.parent
-  let absOffset = if it2 != nil: it2.render.offset else: offset(0, 0)
-  var offset = absOffset
+  var offset = if it2 != nil: it2.render.offset else: offset(0, 0)
   for i in countdown(toPosition.high, 0):
     let it = toPosition[i]
     offset += it.state.offset
@@ -507,6 +509,7 @@ proc resolveBlockOffset(box: CSSBox): Offset =
     )
     it.inheritClipBox(parent)
     parent = it
+  let absOffset = if abs != nil: abs.render.offset else: offset(0, 0)
   for dim in DimensionType:
     if dim in dims:
       offset[dim] = absOffset[dim]
diff --git a/test/layout/absolute-negative-z-index-position-resolved-before-container.color.expected b/test/layout/absolute-negative-z-index-position-resolved-before-container.color.expected
new file mode 100644
index 00000000..15f88013
--- /dev/null
+++ b/test/layout/absolute-negative-z-index-position-resolved-before-container.color.expected
@@ -0,0 +1 @@
+                      
diff --git a/test/layout/absolute-negative-z-index-position-resolved-before-container.html b/test/layout/absolute-negative-z-index-position-resolved-before-container.html
new file mode 100644
index 00000000..ff5bb29b
--- /dev/null
+++ b/test/layout/absolute-negative-z-index-position-resolved-before-container.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<div style="position: absolute; margin-left: 1ch">
+<div style="position: absolute; margin-left: 1ch">
+<div style="width: 10em; height: 1em; left: 0; position: absolute; z-index: -1; background: red"></div>