Selaa lähdekoodia

LibWeb: Handle negative values when collapsing vertical margins

In the presence of negative margins, we subtract the largest negative
margin from max(0, largest positive margin).
Andreas Kling 5 vuotta sitten
vanhempi
commit
c91981eba8

+ 23 - 0
Base/home/anon/www/margin-collapse-2.html

@@ -0,0 +1,23 @@
+<style>
+#foo {
+    border: 1px solid red;
+    margin-bottom: 25px;
+    width: 100px;
+    height: 100px;
+}
+#bar {
+    border: 1px solid green;
+    margin-bottom: 25px;
+    width: 100px;
+    height: 100px;
+}
+#baz {
+    border: 1px solid blue;
+    width: 100px;
+    margin-top: -20px;
+    height: 100px;
+}
+</style>
+<div id=foo>foo</div>
+<div id=bar>bar</div>
+<div id=baz>baz</div>

+ 1 - 0
Base/home/anon/www/welcome.html

@@ -28,6 +28,7 @@ span#ua {
     <p>Your user agent is: <b><span id="ua"></span></b></p>
     <p>Your user agent is: <b><span id="ua"></span></b></p>
     <p>Some small test pages:</p>
     <p>Some small test pages:</p>
     <ul>
     <ul>
+        <li><a href="margin-collapse-2.html">margin collapsing 2</a></li>
         <li><a href="margin-collapse-1.html">margin collapsing 1</a></li>
         <li><a href="margin-collapse-1.html">margin collapsing 1</a></li>
         <li><a href="position-absolute-from-edges.html">position: absolute, offset from edges</a></li>
         <li><a href="position-absolute-from-edges.html">position: absolute, offset from edges</a></li>
         <li><a href="iframe.html">iframe</a></li>
         <li><a href="iframe.html">iframe</a></li>

+ 8 - 1
Libraries/LibWeb/Layout/LayoutBlock.cpp

@@ -481,7 +481,14 @@ void LayoutBlock::compute_position()
         // Collapse top margin with bottom margin of previous sibling if necessary
         // Collapse top margin with bottom margin of previous sibling if necessary
         float previous_sibling_margin_bottom = previous_sibling_style.margin().bottom.to_px(*relevant_sibling);
         float previous_sibling_margin_bottom = previous_sibling_style.margin().bottom.to_px(*relevant_sibling);
         float my_margin_top = box_model().margin().top.to_px(*this);
         float my_margin_top = box_model().margin().top.to_px(*this);
-        if (previous_sibling_margin_bottom > my_margin_top) {
+
+        if (my_margin_top < 0 || previous_sibling_margin_bottom < 0) {
+            // Negative margins present.
+            float largest_negative_margin = -min(my_margin_top, previous_sibling_margin_bottom);
+            float largest_positive_margin = (my_margin_top < 0 && previous_sibling_margin_bottom < 0) ? 0 : max(my_margin_top, previous_sibling_margin_bottom);
+            float final_margin = largest_positive_margin - largest_negative_margin;
+            position_y += final_margin - my_margin_top;
+        } else if (previous_sibling_margin_bottom > my_margin_top) {
             // Sibling's margin is larger than mine, adjust so we use sibling's.
             // Sibling's margin is larger than mine, adjust so we use sibling's.
             position_y += previous_sibling_margin_bottom - my_margin_top;
             position_y += previous_sibling_margin_bottom - my_margin_top;
         }
         }