diff --git a/Base/res/html/misc/clear-1.html b/Base/res/html/misc/clear-1.html
new file mode 100644
index 00000000000..3e2d9b86751
--- /dev/null
+++ b/Base/res/html/misc/clear-1.html
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+ lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
+ lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
+ lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
+ lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
+
+
+ lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum
+
+
diff --git a/Base/res/html/misc/welcome.html b/Base/res/html/misc/welcome.html
index d1fc359efd8..c976d522d5d 100644
--- a/Base/res/html/misc/welcome.html
+++ b/Base/res/html/misc/welcome.html
@@ -38,6 +38,7 @@ span#loadtime {
This page loaded in ms
Some small test pages:
+ - clearing floats
- floating boxes
- inline elements with padding
- event bubbling and multiple listeners
diff --git a/Libraries/LibWeb/CSS/StyleProperties.cpp b/Libraries/LibWeb/CSS/StyleProperties.cpp
index 386cf101f4d..3598bf7148e 100644
--- a/Libraries/LibWeb/CSS/StyleProperties.cpp
+++ b/Libraries/LibWeb/CSS/StyleProperties.cpp
@@ -303,6 +303,23 @@ Optional StyleProperties::float_() const
return {};
}
+Optional StyleProperties::clear() const
+{
+ auto value = property(CSS::PropertyID::Clear);
+ if (!value.has_value() || !value.value()->is_string())
+ return {};
+ auto string = value.value()->to_string();
+ if (string == "none")
+ return CSS::Clear::None;
+ if (string == "left")
+ return CSS::Clear::Left;
+ if (string == "right")
+ return CSS::Clear::Right;
+ if (string == "both")
+ return CSS::Clear::Both;
+ return {};
+}
+
CSS::Display StyleProperties::display() const
{
auto display = string_or_fallback(CSS::PropertyID::Display, "inline");
diff --git a/Libraries/LibWeb/CSS/StyleProperties.h b/Libraries/LibWeb/CSS/StyleProperties.h
index 924575e6e36..f8fd7cc2c59 100644
--- a/Libraries/LibWeb/CSS/StyleProperties.h
+++ b/Libraries/LibWeb/CSS/StyleProperties.h
@@ -63,6 +63,7 @@ public:
CSS::TextAlign text_align() const;
CSS::Display display() const;
Optional float_() const;
+ Optional clear() const;
Optional white_space() const;
Optional line_style(CSS::PropertyID) const;
diff --git a/Libraries/LibWeb/CSS/StyleValue.h b/Libraries/LibWeb/CSS/StyleValue.h
index 6d4d8cb953e..1d8da443e92 100644
--- a/Libraries/LibWeb/CSS/StyleValue.h
+++ b/Libraries/LibWeb/CSS/StyleValue.h
@@ -149,6 +149,13 @@ enum class Float {
Right,
};
+enum class Clear {
+ None,
+ Left,
+ Right,
+ Both,
+};
+
enum class LineStyle {
None,
Hidden,
diff --git a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
index f344bac7b6f..a95e341cd8c 100644
--- a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
+++ b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
@@ -565,6 +565,28 @@ void BlockFormattingContext::place_block_level_non_replaced_element_in_normal_fl
}
}
+ if (box.style().clear() == CSS::Clear::Left || box.style().clear() == CSS::Clear::Both) {
+ if (!m_left_floating_boxes.is_empty()) {
+ float clearance_y = 0;
+ for (auto* floating_box : m_left_floating_boxes) {
+ clearance_y = max(clearance_y, floating_box->effective_offset().y() + floating_box->box_model().margin_box(*floating_box).bottom);
+ }
+ y = max(y, clearance_y);
+ m_left_floating_boxes.clear();
+ }
+ }
+
+ if (box.style().clear() == CSS::Clear::Right || box.style().clear() == CSS::Clear::Both) {
+ if (!m_right_floating_boxes.is_empty()) {
+ float clearance_y = 0;
+ for (auto* floating_box : m_right_floating_boxes) {
+ clearance_y = max(clearance_y, floating_box->effective_offset().y() + floating_box->box_model().margin_box(*floating_box).bottom);
+ }
+ y = max(y, clearance_y);
+ m_right_floating_boxes.clear();
+ }
+ }
+
box.set_offset(x, y);
}
diff --git a/Libraries/LibWeb/Layout/LayoutStyle.h b/Libraries/LibWeb/Layout/LayoutStyle.h
index dba8290de4f..1dcf796889b 100644
--- a/Libraries/LibWeb/Layout/LayoutStyle.h
+++ b/Libraries/LibWeb/Layout/LayoutStyle.h
@@ -35,6 +35,7 @@ namespace Web {
class InitialValues {
public:
static CSS::Float float_() { return CSS::Float::None; }
+ static CSS::Clear clear() { return CSS::Clear::None; }
static CSS::WhiteSpace white_space() { return CSS::WhiteSpace::Normal; }
};
@@ -48,6 +49,7 @@ public:
class LayoutStyle {
public:
CSS::Float float_() const { return m_float; }
+ CSS::Clear clear() const { return m_clear; }
Optional z_index() const { return m_z_index; }
CSS::TextAlign text_align() const { return m_text_align; }
CSS::Position position() const { return m_position; }
@@ -70,6 +72,7 @@ public:
protected:
CSS::Float m_float { InitialValues::float_() };
+ CSS::Clear m_clear { InitialValues::clear() };
Optional m_z_index;
CSS::TextAlign m_text_align;
CSS::Position m_position;
@@ -95,6 +98,7 @@ class ImmutableLayoutStyle final : public LayoutStyle {
class MutableLayoutStyle final : public LayoutStyle {
public:
void set_float(CSS::Float value) { m_float = value; }
+ void set_clear(CSS::Clear value) { m_clear = value; }
void set_z_index(Optional value) { m_z_index = value; }
void set_text_align(CSS::TextAlign text_align) { m_text_align = text_align; }
void set_position(CSS::Position position) { m_position = position; }
diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp
index cb2779ddf47..51976f47bb8 100644
--- a/Libraries/LibWeb/Layout/Node.cpp
+++ b/Libraries/LibWeb/Layout/Node.cpp
@@ -231,6 +231,10 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style)
if (float_.has_value())
style.set_float(float_.value());
+ auto clear = specified_style.clear();
+ if (clear.has_value())
+ style.set_clear(clear.value());
+
style.set_z_index(specified_style.z_index());
style.set_width(specified_style.length_or_fallback(CSS::PropertyID::Width, {}));
style.set_min_width(specified_style.length_or_fallback(CSS::PropertyID::MinWidth, {}));