diff --git a/Base/res/html/misc/clear-1.html b/Base/res/html/misc/clear-1.html
new file mode 100644
index 0000000000..3e2d9b8675
--- /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 d1fc359efd..c976d522d5 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 386cf101f4..3598bf7148 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 924575e6e3..f8fd7cc2c5 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 6d4d8cb953..1d8da443e9 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 f344bac7b6..a95e341cd8 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 dba8290de4..1dcf796889 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 cb2779ddf4..51976f47bb 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, {}));