瀏覽代碼

LibWeb: Make sure collapsed margins are not ignored if box creates FC

Fixes a bug that if box creates new formatting context then all already
collapsed margins are ignored and only margin_top is used.
Aliaksandr Kalenik 2 年之前
父節點
當前提交
76aa17be86

+ 6 - 0
Tests/LibWeb/Layout/expected/block-and-inline/margin-collapse-6.txt

@@ -0,0 +1,6 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x106 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x90 children: not-inline
+      BlockContainer <div.upper> at (8,8) content-size 784x20 children: not-inline
+      BlockContainer <div.bfc> at (8,78) content-size 784x20 [BFC] children: not-inline
+        BlockContainer <div.inner> at (8,78) content-size 20x20 children: not-inline

+ 15 - 0
Tests/LibWeb/Layout/input/block-and-inline/margin-collapse-6.html

@@ -0,0 +1,15 @@
+<!doctype html><style>
+    .upper { 
+        margin-bottom: 50px;
+        height: 20px;
+        background: lime;
+    }
+    .bfc {
+        display: flow-root;
+    }
+    .inner {
+        width: 20px;
+        height: 20px;
+        background: black;
+    }
+</style><div class="upper"></div><div class=bfc><div class="inner">

+ 9 - 12
Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp

@@ -553,23 +553,20 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain
         m_margin_state.reset();
     }
 
-    CSSPixels margin_top = 0;
     auto independent_formatting_context = create_independent_formatting_context_if_needed(m_state, box);
 
+    m_margin_state.add_margin(box_state.margin_top);
+    m_margin_state.update_block_waiting_for_final_y_position();
+    CSSPixels margin_top = m_margin_state.current_collapsed_margin();
+
+    if (m_margin_state.has_block_container_waiting_for_final_y_position()) {
+        // If first child margin top will collapse with margin-top of containing block then margin-top of child is 0
+        margin_top = 0;
+    }
+
     if (independent_formatting_context) {
         // Margins of elements that establish new formatting contexts do not collapse with their in-flow children
         m_margin_state.reset();
-
-        margin_top = box_state.margin_top;
-    } else {
-        m_margin_state.add_margin(box_state.margin_top);
-        m_margin_state.update_block_waiting_for_final_y_position();
-
-        margin_top = m_margin_state.current_collapsed_margin();
-        if (m_margin_state.has_block_container_waiting_for_final_y_position()) {
-            // If first child margin top will collapse with margin-top of containing block then margin-top of child is 0
-            margin_top = 0;
-        }
     }
 
     place_block_level_element_in_normal_flow_vertically(box, y + margin_top);