Repository: Kozea/WeasyPrint

Issue:
Table cell min-width is ignored when another cell has overflowing text
Two tables here to compare, note the `min-width` css rule:

```html
<head>
<style>
table td { border: 1px solid black; }
table.key-val tr td:nth-child(1) { min-width: 13em; }
</style>
</head>

<body>
<table class="key-val">
    <tbody>
        <tr>
            <td>Normal Key 1</td>
            <td>Normal Value 1</td>
        </tr>
        <tr>
            <td>Normal Key 2</td>
           <td>Normal Value 2</td>
        </tr>
    </tbody>
</table>
<br>
<table class="key-val">
    <tbody>
        <tr>
            <td>Short value</td>
            <td>Works as expected</td>
        </tr>
        <tr>
            <td>Long Value</td>
            <td>Annoyingly breaks my table layout: Sed ut perspiciatis unde omnis iste natus error sit voluptatem
                accusantium doloremque laudantium, totam rem aperiam,
                eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
            </td>
        </tr>
    </tbody>
</table>
</body>
```

Firefox:
![image](https://user-images.githubusercontent.com/3399022/122417277-a9bae880-cf89-11eb-94af-2891db73300d.png)

Weasyprint:
![image](https://user-images.githubusercontent.com/3399022/122417643-ec7cc080-cf89-11eb-9a48-ee3bd5e748c7.png)

I have experimented with different width units as well as tried adjusting `overflow-wrap` with no effect on Weasyprint's result.

Discussion:

Patch:
diff --git a/weasyprint/layout/preferred.py b/weasyprint/layout/preferred.py
index c508399d..be8150c9 100644
--- a/weasyprint/layout/preferred.py
+++ b/weasyprint/layout/preferred.py
@@ -225,8 +225,15 @@ def column_group_content_width(context, box):
 
 def table_cell_min_content_width(context, box, outer):
     """Return the min-content width for a ``TableCellBox``."""
+    # See https://www.w3.org/TR/css-tables-3/#outer-min-content
+    min_width = box.style['min_width']
+    if min_width == 'auto':
+        min_width = 0
+    else:
+        min_width = min_width.value
     children_widths = [
-        min_content_width(context, child) for child in box.children
+        max(min_width, min_content_width(context, child))
+        for child in box.children
         if not child.is_absolutely_positioned()]
     children_min_width = margin_width(
         box, max(children_widths) if children_widths else 0)


Test patch:
diff --git a/tests/layout/test_table.py b/tests/layout/test_table.py
index 12c6cb92..2832ef8c 100644
--- a/tests/layout/test_table.py
+++ b/tests/layout/test_table.py
@@ -2912,3 +2912,64 @@ def test_table_different_display():
         </td>
       </table>
     ''')
+
+
+@assert_no_logs
+def test_min_width_with_overflow():
+    # issue 1383
+    page, = render_pages('''
+<head>
+<style>
+table td { border: 1px solid black; }
+table.key-val tr td:nth-child(1) { min-width: 13em; }
+</style>
+</head>
+
+<body>
+<table class="key-val">
+    <tbody>
+        <tr>
+            <td>Normal Key 1</td>
+            <td>Normal Value 1</td>
+        </tr>
+        <tr>
+            <td>Normal Key 2</td>
+           <td>Normal Value 2</td>
+        </tr>
+    </tbody>
+</table>
+<table class="key-val">
+    <tbody>
+        <tr>
+            <td>Short value</td>
+            <td>Works as expected</td>
+        </tr>
+        <tr>
+            <td>Long Value</td>
+            <td>Annoyingly breaks my table layout: Sed ut perspiciatis
+                unde omnis iste natus error sit voluptatem
+                accusantium doloremque laudantium, totam rem aperiam,
+                eaque ipsa quae ab illo inventore veritatis et quasi
+                architecto beatae vitae dicta sunt explicabo.
+            </td>
+        </tr>
+    </tbody>
+</table>
+</body>
+    ''')
+    html, = page.children
+    body, = html.children
+    table_wrapper_1, table_wrapper_2 = body.children
+
+    table1, = table_wrapper_1.children
+    tbody1, = table1.children
+    tr1, tr2 = tbody1.children
+    table1_td1, table1_td2 = tr1.children
+
+    table2, = table_wrapper_2.children
+    tbody2, = table2.children
+    tr1, tr2 = tbody2.children
+    table2_td1, table2_td2 = tr1.children
+
+    assert table1_td1.min_width == table2_td1.min_width
+    assert table1_td1.width == table2_td1.width