diff --git a/src/browser/StyleManager.zig b/src/browser/StyleManager.zig
index 59d441515..0f8f8af9f 100644
--- a/src/browser/StyleManager.zig
+++ b/src/browser/StyleManager.zig
@@ -20,6 +20,7 @@ const std = @import("std");
const lp = @import("lightpanda");
const Frame = @import("Frame.zig");
+const Viewport = @import("Viewport.zig");
const units = @import("css/units.zig");
const CssParser = @import("css/Parser.zig");
@@ -40,7 +41,7 @@ const String = lp.String;
const Allocator = std.mem.Allocator;
// Tracks the CSS properties the renderless layout acts on (display, visibility,
-// opacity, pointer-events, overflow) from
+
+
+
+
+
+
diff --git a/src/browser/webapi/CSS.zig b/src/browser/webapi/CSS.zig
index 213064d7b..136b8a276 100644
--- a/src/browser/webapi/CSS.zig
+++ b/src/browser/webapi/CSS.zig
@@ -19,7 +19,6 @@
const std = @import("std");
const js = @import("../js/js.zig");
const Frame = @import("../Frame.zig");
-const units = @import("../css/units.zig");
const Tokenizer = @import("../css/Tokenizer.zig");
const CSS = @This();
@@ -27,18 +26,6 @@ _pad: bool = false,
pub const init: CSS = .{};
-// parseDimension plus viewport-relative units, which the faux layout
-// resolves against the page viewport.
-pub fn parseDimensionViewport(value: []const u8, frame: *Frame) ?f64 {
- const parsed = units.parse(value) catch return null;
- return switch (parsed.unit) {
- .none, .px => parsed.value,
- .vh => parsed.value * @as(f64, @floatFromInt(frame.page.getViewport().height)) / 100.0,
- .vw => parsed.value * @as(f64, @floatFromInt(frame.page.getViewport().width)) / 100.0,
- else => null,
- };
-}
-
// Extract the X value from a transfrom. This could come from a translate,
// translatex, translate3d or matrix function.
pub fn parseTranslateX(value: []const u8) f64 {
diff --git a/src/browser/webapi/Element.zig b/src/browser/webapi/Element.zig
index 89ba05b9b..741ba73a8 100644
--- a/src/browser/webapi/Element.zig
+++ b/src/browser/webapi/Element.zig
@@ -1497,27 +1497,34 @@ pub const Axis = enum {
};
pub fn getElementAxis(self: *Element, frame: *Frame, comptime axis: Axis) Axis.State {
- if (self.inlineStyle(frame)) |style| {
- const decl = style.asCSSStyleDeclaration();
- if (CSS.parseDimensionViewport(decl.getPropertyValue(@tagName(axis), frame), frame)) |v| {
+ const tag = self.getTag();
+ const root = tag == .html or tag == .body;
+
+ if (self.ownerFrame(frame)) |owner| {
+ const style_manager = &owner._style_manager;
+ // Roots take only an inline size: a sheet's `height: 100vh` on body
+ // would shrink the box every synthetic position must fit in.
+ const size = if (root) style_manager.inlineSize(self, axis) else style_manager.declaredSize(self, axis);
+ if (size) |v| {
return .{ .value = v, .explicit = true };
}
}
- switch (self.getTag()) {
- // Root containers get large default size to contain descendant positions.
- // With calculateDocumentPosition using linear depth scaling (100px per level),
- // even very deep trees (100 levels) stay within 10,000px.
- // 100M pixels is plausible for very long documents.
- .html, .body => return .{ .value = if (axis == .width) 1920.0 else 100_000_000.0 },
- .img, .iframe => {
- if (self.getAttributeSafe(comptime .wrap(@tagName(axis)))) |attr| {
- if (std.fmt.parseFloat(f64, attr)) |parsed| {
- return .{ .value = parsed, .explicit = true };
- } else |_| {}
- }
- },
- else => {},
+ // Root containers get large default size to contain descendant positions.
+ // With calculateDocumentPosition using linear depth scaling (100px per level),
+ // even very deep trees (100 levels) stay within 10,000px.
+ // 100M pixels is plausible for very long documents.
+ if (root) {
+ return .{ .value = if (axis == .width) 1920.0 else 100_000_000.0 };
+ }
+
+ // Presentational attributes lose to CSS sizes.
+ if (tag == .img or tag == .iframe) {
+ if (self.getAttributeSafe(comptime .wrap(@tagName(axis)))) |attr| {
+ if (std.fmt.parseFloat(f64, attr)) |parsed| {
+ return .{ .value = parsed, .explicit = true };
+ } else |_| {}
+ }
}
return .{ .value = 5.0 };