diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp index e245c2459d..c82cfd34f6 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp +++ b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp @@ -183,6 +183,15 @@ void LayoutState::UsedValues::set_node(NodeWithStyleAndBoxModelMetrics& node, Us { m_node = &node; + // NOTE: In the code below, we decide if `node` has definite width and/or height. + // This attempts to cover all the *general* cases where CSS considers sizes to be definite. + // If `node` has definite values for min/max-width or min/max-height and a definite + // preferred size in the same axis, we clamp the preferred size here as well. + // + // There are additional cases where CSS considers values to be definite. We model all of + // those by having our engine consider sizes to be definite *once they are assigned to + // the UsedValues by calling set_content_width() or set_content_height(). + auto const& computed_values = node.computed_values(); auto is_definite_size = [&](CSS::Size const& size, float& resolved_definite_size, bool width) { @@ -252,8 +261,32 @@ void LayoutState::UsedValues::set_node(NodeWithStyleAndBoxModelMetrics& node, Us return false; }; + float min_width = 0; + bool has_definite_min_width = is_definite_size(computed_values.min_width(), min_width, true); + float max_width = 0; + bool has_definite_max_width = is_definite_size(computed_values.max_width(), max_width, true); + + float min_height = 0; + bool has_definite_min_height = is_definite_size(computed_values.min_height(), min_height, false); + float max_height = 0; + bool has_definite_max_height = is_definite_size(computed_values.max_height(), max_height, false); + m_has_definite_width = is_definite_size(computed_values.width(), m_content_width, true); m_has_definite_height = is_definite_size(computed_values.height(), m_content_height, false); + + if (m_has_definite_width) { + if (has_definite_min_width) + m_content_width = max(min_width, m_content_width); + if (has_definite_max_width) + m_content_width = min(max_width, m_content_width); + } + + if (m_has_definite_height) { + if (has_definite_min_height) + m_content_height = max(min_height, m_content_height); + if (has_definite_max_height) + m_content_height = min(max_height, m_content_height); + } } void LayoutState::UsedValues::set_content_width(float width)