diff --git a/weasyprint/layout/blocks.py b/weasyprint/layout/blocks.py
index b0b5efe28..56c59eee6 100644
--- a/weasyprint/layout/blocks.py
+++ b/weasyprint/layout/blocks.py
@@ -461,7 +461,6 @@ def block_container_layout(context, box, max_position_y, skip_stack,
new_containing_block = box
if not new_containing_block.is_table_wrapper:
- # TODO: there's no collapsing margins inside tables, right?
resolve_percentages(child, new_containing_block)
if (child.is_in_normal_flow() and
last_in_flow_child is None and
@@ -493,7 +492,7 @@ def block_container_layout(context, box, max_position_y, skip_stack,
adjoining_margins = []
position_y = box.content_box_y()
- if adjoining_margins and isinstance(child, boxes.TableBox):
+ if adjoining_margins and box.is_table_wrapper:
collapsed_margin = collapse_margin(adjoining_margins)
child.position_y += collapsed_margin
position_y += collapsed_margin
@@ -625,8 +624,11 @@ def block_container_layout(context, box, max_position_y, skip_stack,
# not adjoining. (position_y is not used afterwards.)
adjoining_margins = []
- if box.border_bottom_width or box.padding_bottom or (
- establishes_formatting_context(box) or box.is_for_root_element):
+ if (box.border_bottom_width or
+ box.padding_bottom or
+ establishes_formatting_context(box) or
+ box.is_for_root_element or
+ box.is_table_wrapper):
position_y += collapse_margin(adjoining_margins)
adjoining_margins = []
diff --git a/weasyprint/tests/test_layout/test_table.py b/weasyprint/tests/test_layout/test_table.py
index 8519ed04b..eaf409ce8 100644
--- a/weasyprint/tests/test_layout/test_table.py
+++ b/weasyprint/tests/test_layout/test_table.py
@@ -2075,3 +2075,61 @@ def test_inline_table_baseline(vertical_align, table_position_y):
assert text1.position_y == text2.position_y == 0
assert table.height == 10 * 2
assert table.position_y == table_position_y
+
+
+@assert_no_logs
+def test_table_caption_margin_top():
+ page, = render_pages('''
+
+
+
+
+ ''')
+ html, = page.children
+ body, = html.children
+ h1, wrapper, h2 = body.children
+ caption, table = wrapper.children
+ tbody, = table.children
+ assert (h1.content_box_x(), h1.content_box_y()) == (20, 20)
+ assert (wrapper.content_box_x(), wrapper.content_box_y()) == (20, 50)
+ assert (caption.content_box_x(), caption.content_box_y()) == (40, 70)
+ assert (tbody.content_box_x(), tbody.content_box_y()) == (20, 100)
+ assert (h2.content_box_x(), h2.content_box_y()) == (20, 130)
+
+
+@assert_no_logs
+def test_table_caption_margin_bottom():
+ page, = render_pages('''
+
+
+
+
+ ''')
+ html, = page.children
+ body, = html.children
+ h1, wrapper, h2 = body.children
+ table, caption = wrapper.children
+ tbody, = table.children
+ assert (h1.content_box_x(), h1.content_box_y()) == (20, 20)
+ assert (wrapper.content_box_x(), wrapper.content_box_y()) == (20, 50)
+ assert (tbody.content_box_x(), tbody.content_box_y()) == (20, 50)
+ assert (caption.content_box_x(), caption.content_box_y()) == (40, 80)
+ assert (h2.content_box_x(), h2.content_box_y()) == (20, 130)