diff --git a/clippy.toml b/clippy.toml
index 70fbe707..de970d87 100644
--- a/clippy.toml
+++ b/clippy.toml
@@ -4,4 +4,6 @@ disallowed-methods = [
     { path = "web_sys::HtmlCanvasElement::height", reason = "Winit shouldn't touch the internal canvas size" },
     { path = "web_sys::HtmlCanvasElement::set_width", reason = "Winit shouldn't touch the internal canvas size" },
     { path = "web_sys::HtmlCanvasElement::set_height", reason = "Winit shouldn't touch the internal canvas size" },
+    { path = "web_sys::Window::document", reason = "cache this to reduce calls to JS" },
+    { path = "web_sys::Window::get_computed_style", reason = "cache this to reduce calls to JS" },
 ]
diff --git a/src/platform_impl/web/event_loop/runner.rs b/src/platform_impl/web/event_loop/runner.rs
index 4fd68ade..dd71a325 100644
--- a/src/platform_impl/web/event_loop/runner.rs
+++ b/src/platform_impl/web/event_loop/runner.rs
@@ -19,7 +19,7 @@ use std::{
     rc::{Rc, Weak},
 };
 use wasm_bindgen::prelude::Closure;
-use web_sys::{KeyboardEvent, PageTransitionEvent, PointerEvent, WheelEvent};
+use web_sys::{Document, KeyboardEvent, PageTransitionEvent, PointerEvent, WheelEvent};
 use web_time::{Duration, Instant};
 
 pub struct Shared<T: 'static>(Rc<Execution<T>>);
@@ -41,6 +41,7 @@ pub struct Execution<T: 'static> {
     events: RefCell<VecDeque<EventWrapper<T>>>,
     id: RefCell<u32>,
     window: web_sys::Window,
+    document: Document,
     all_canvases: RefCell<Vec<(WindowId, Weak<RefCell<backend::Canvas>>)>>,
     redraw_pending: RefCell<HashSet<WindowId>>,
     destroy_pending: RefCell<VecDeque<WindowId>>,
@@ -141,13 +142,18 @@ impl<T: 'static> Runner<T> {
 
 impl<T: 'static> Shared<T> {
     pub fn new() -> Self {
+        #[allow(clippy::disallowed_methods)]
+        let window = web_sys::window().expect("only callable from inside the `Window`");
+        #[allow(clippy::disallowed_methods)]
+        let document = window.document().expect("Failed to obtain document");
+
         Shared(Rc::new(Execution {
             runner: RefCell::new(RunnerEnum::Pending),
             suspended: Cell::new(false),
             event_loop_recreation: Cell::new(false),
             events: RefCell::new(VecDeque::new()),
-            #[allow(clippy::disallowed_methods)]
-            window: web_sys::window().expect("only callable from inside the `Window`"),
+            window,
+            document,
             id: RefCell::new(0),
             all_canvases: RefCell::new(Vec::new()),
             redraw_pending: RefCell::new(HashSet::new()),
@@ -168,6 +174,10 @@ impl<T: 'static> Shared<T> {
         &self.0.window
     }
 
+    pub fn document(&self) -> &Document {
+        &self.0.document
+    }
+
     pub fn add_canvas(&self, id: WindowId, canvas: &Rc<RefCell<backend::Canvas>>) {
         self.0
             .all_canvases
@@ -394,13 +404,13 @@ impl<T: 'static> Shared<T> {
         let runner = self.clone();
         *self.0.on_visibility_change.borrow_mut() = Some(EventListenerHandle::new(
             // Safari <14 doesn't support the `visibilitychange` event on `Window`.
-            &self.window().document().expect("Failed to obtain document"),
+            self.document(),
             "visibilitychange",
             Closure::new(move |_| {
                 if !runner.0.suspended.get() {
                     for (id, canvas) in &*runner.0.all_canvases.borrow() {
                         if let Some(canvas) = canvas.upgrade() {
-                            let is_visible = backend::is_visible(runner.window());
+                            let is_visible = backend::is_visible(runner.document());
                             // only fire if:
                             // - not visible and intersects
                             // - not visible and we don't know if it intersects yet
diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs
index faf2403a..72893f06 100644
--- a/src/platform_impl/web/event_loop/window_target.rs
+++ b/src/platform_impl/web/event_loop/window_target.rs
@@ -725,7 +725,7 @@ impl<T> EventLoopWindowTarget<T> {
         let runner = self.runner.clone();
         canvas.on_intersection(move |is_intersecting| {
             // only fire if visible while skipping the first event if it's intersecting
-            if backend::is_visible(runner.window())
+            if backend::is_visible(runner.document())
                 && !(is_intersecting && canvas_clone.borrow().is_intersecting.is_none())
             {
                 runner.send_event(Event::WindowEvent {
diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs
index 8ef4f38f..14f842fc 100644
--- a/src/platform_impl/web/web_sys/canvas.rs
+++ b/src/platform_impl/web/web_sys/canvas.rs
@@ -21,7 +21,9 @@ use smol_str::SmolStr;
 use wasm_bindgen::prelude::wasm_bindgen;
 use wasm_bindgen::{closure::Closure, JsCast, JsValue};
 use wasm_bindgen_futures::JsFuture;
-use web_sys::{Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, WheelEvent};
+use web_sys::{
+    CssStyleDeclaration, Document, Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, WheelEvent,
+};
 
 #[allow(dead_code)]
 pub struct Canvas {
@@ -44,8 +46,10 @@ pub struct Canvas {
 
 pub struct Common {
     pub window: web_sys::Window,
+    pub document: Document,
     /// Note: resizing the HTMLCanvasElement should go through `backend::set_canvas_size` to ensure the DPI factor is maintained.
     pub raw: HtmlCanvasElement,
+    style: CssStyleDeclaration,
     old_size: Rc<Cell<PhysicalSize<u32>>>,
     current_size: Rc<Cell<PhysicalSize<u32>>>,
     wants_fullscreen: Rc<RefCell<bool>>,
@@ -55,21 +59,16 @@ impl Canvas {
     pub fn create(
         id: WindowId,
         window: web_sys::Window,
+        document: Document,
         attr: &WindowAttributes,
         platform_attr: PlatformSpecificWindowBuilderAttributes,
     ) -> Result<Self, RootOE> {
         let canvas = match platform_attr.canvas {
             Some(canvas) => canvas,
-            None => {
-                let document = window
-                    .document()
-                    .ok_or_else(|| os_error!(OsError("Failed to obtain document".to_owned())))?;
-
-                document
-                    .create_element("canvas")
-                    .map_err(|_| os_error!(OsError("Failed to create canvas element".to_owned())))?
-                    .unchecked_into()
-            }
+            None => document
+                .create_element("canvas")
+                .map_err(|_| os_error!(OsError("Failed to create canvas element".to_owned())))?
+                .unchecked_into(),
         };
 
         // A tabindex is needed in order to capture local keyboard events.
@@ -83,15 +82,24 @@ impl Canvas {
                 .map_err(|_| os_error!(OsError("Failed to set a tabindex".to_owned())))?;
         }
 
+        #[allow(clippy::disallowed_methods)]
+        let style = window
+            .get_computed_style(&canvas)
+            .expect("Failed to obtain computed style")
+            // this can't fail: we aren't using a pseudo-element
+            .expect("Invalid pseudo-element");
+
         if let Some(size) = attr.inner_size {
             let size = size.to_logical(super::scale_factor(&window));
-            super::set_canvas_size(&window, &canvas, size);
+            super::set_canvas_size(&document, &canvas, &style, size);
         }
 
         Ok(Canvas {
             common: Common {
                 window,
+                document,
                 raw: canvas,
+                style,
                 old_size: Rc::default(),
                 current_size: Rc::default(),
                 wants_fullscreen: Rc::new(RefCell::new(false)),
@@ -117,12 +125,7 @@ impl Canvas {
         if lock {
             self.raw().request_pointer_lock();
         } else {
-            let document = self
-                .common
-                .window
-                .document()
-                .ok_or_else(|| os_error!(OsError("Failed to obtain document".to_owned())))?;
-            document.exit_pointer_lock();
+            self.common.document.exit_pointer_lock();
         }
         Ok(())
     }
@@ -141,50 +144,58 @@ impl Canvas {
             y: bounds.y(),
         };
 
-        let document = self.window().document().expect("Failed to obtain document");
-
-        if document.contains(Some(self.raw())) {
-            let style = self
-                .window()
-                .get_computed_style(self.raw())
-                .expect("Failed to obtain computed style")
-                // this can't fail: we aren't using a pseudo-element
-                .expect("Invalid pseudo-element");
-            if style.get_property_value("display").unwrap() != "none" {
-                position.x += super::style_size_property(&style, "border-left-width")
-                    + super::style_size_property(&style, "padding-left");
-                position.y += super::style_size_property(&style, "border-top-width")
-                    + super::style_size_property(&style, "padding-top");
-            }
+        if self.document().contains(Some(self.raw()))
+            && self.style().get_property_value("display").unwrap() != "none"
+        {
+            position.x += super::style_size_property(self.style(), "border-left-width")
+                + super::style_size_property(self.style(), "padding-left");
+            position.y += super::style_size_property(self.style(), "border-top-width")
+                + super::style_size_property(self.style(), "padding-top");
         }
 
         position
     }
 
+    #[inline]
     pub fn old_size(&self) -> PhysicalSize<u32> {
         self.common.old_size.get()
     }
 
+    #[inline]
     pub fn inner_size(&self) -> PhysicalSize<u32> {
         self.common.current_size.get()
     }
 
+    #[inline]
     pub fn set_old_size(&self, size: PhysicalSize<u32>) {
         self.common.old_size.set(size)
     }
 
+    #[inline]
     pub fn set_current_size(&self, size: PhysicalSize<u32>) {
         self.common.current_size.set(size)
     }
 
+    #[inline]
     pub fn window(&self) -> &web_sys::Window {
         &self.common.window
     }
 
+    #[inline]
+    pub fn document(&self) -> &Document {
+        &self.common.document
+    }
+
+    #[inline]
     pub fn raw(&self) -> &HtmlCanvasElement {
         &self.common.raw
     }
 
+    #[inline]
+    pub fn style(&self) -> &CssStyleDeclaration {
+        &self.common.style
+    }
+
     pub fn on_touch_start(&mut self, prevent_default: bool) {
         self.on_touch_start = Some(self.common.add_event("touchstart", move |event: Event| {
             if prevent_default {
@@ -382,7 +393,9 @@ impl Canvas {
     {
         self.on_resize_scale = Some(ResizeScaleHandle::new(
             self.window().clone(),
+            self.document().clone(),
             self.raw().clone(),
+            self.style().clone(),
             scale_handler,
             size_handler,
         ));
@@ -425,7 +438,7 @@ impl Canvas {
             // Then we resize the canvas to the new size, a new
             // `Resized` event will be sent by the `ResizeObserver`:
             let new_size = new_size.to_logical(scale);
-            super::set_canvas_size(self.window(), self.raw(), new_size);
+            super::set_canvas_size(self.document(), self.raw(), self.style(), new_size);
 
             // Set the size might not trigger the event because the calculation is inaccurate.
             self.on_resize_scale
@@ -527,6 +540,6 @@ impl Common {
     }
 
     pub fn is_fullscreen(&self) -> bool {
-        super::is_fullscreen(&self.window, &self.raw)
+        super::is_fullscreen(&self.document, &self.raw)
     }
 }
diff --git a/src/platform_impl/web/web_sys/mod.rs b/src/platform_impl/web/web_sys/mod.rs
index 273c57ca..a45a65ac 100644
--- a/src/platform_impl/web/web_sys/mod.rs
+++ b/src/platform_impl/web/web_sys/mod.rs
@@ -18,16 +18,14 @@ use crate::platform::web::WindowExtWebSys;
 use crate::window::Window;
 use wasm_bindgen::closure::Closure;
 use web_sys::{
-    CssStyleDeclaration, Element, HtmlCanvasElement, PageTransitionEvent, VisibilityState,
+    CssStyleDeclaration, Document, Element, HtmlCanvasElement, PageTransitionEvent, VisibilityState,
 };
 
 pub fn throw(msg: &str) {
     wasm_bindgen::throw_str(msg);
 }
 
-pub fn exit_fullscreen(window: &web_sys::Window) {
-    let document = window.document().expect("Failed to obtain document");
-
+pub fn exit_fullscreen(document: &Document) {
     document.exit_fullscreen();
 }
 
@@ -69,35 +67,28 @@ pub fn scale_factor(window: &web_sys::Window) -> f64 {
 }
 
 pub fn set_canvas_size(
-    window: &web_sys::Window,
+    document: &Document,
     raw: &HtmlCanvasElement,
+    style: &CssStyleDeclaration,
     mut new_size: LogicalSize<f64>,
 ) {
-    let document = window.document().expect("Failed to obtain document");
-
     if !document.contains(Some(raw)) {
         return;
     }
 
-    let style = window
-        .get_computed_style(raw)
-        .expect("Failed to obtain computed style")
-        // this can't fail: we aren't using a pseudo-element
-        .expect("Invalid pseudo-element");
-
     if style.get_property_value("display").unwrap() == "none" {
         return;
     }
 
     if style.get_property_value("box-sizing").unwrap() == "border-box" {
-        new_size.width += style_size_property(&style, "border-left-width")
-            + style_size_property(&style, "border-right-width")
-            + style_size_property(&style, "padding-left")
-            + style_size_property(&style, "padding-right");
-        new_size.height += style_size_property(&style, "border-top-width")
-            + style_size_property(&style, "border-bottom-width")
-            + style_size_property(&style, "padding-top")
-            + style_size_property(&style, "padding-bottom");
+        new_size.width += style_size_property(style, "border-left-width")
+            + style_size_property(style, "border-right-width")
+            + style_size_property(style, "padding-left")
+            + style_size_property(style, "padding-right");
+        new_size.height += style_size_property(style, "border-top-width")
+            + style_size_property(style, "border-bottom-width")
+            + style_size_property(style, "padding-top")
+            + style_size_property(style, "padding-bottom");
     }
 
     set_canvas_style_property(raw, "width", &format!("{}px", new_size.width));
@@ -123,9 +114,7 @@ pub fn set_canvas_style_property(raw: &HtmlCanvasElement, property: &str, value:
         .unwrap_or_else(|err| panic!("error: {err:?}\nFailed to set {property}"))
 }
 
-pub fn is_fullscreen(window: &web_sys::Window, canvas: &HtmlCanvasElement) -> bool {
-    let document = window.document().expect("Failed to obtain document");
-
+pub fn is_fullscreen(document: &Document, canvas: &HtmlCanvasElement) -> bool {
     match document.fullscreen_element() {
         Some(elem) => {
             let canvas: &Element = canvas;
@@ -143,8 +132,7 @@ pub fn is_dark_mode(window: &web_sys::Window) -> Option<bool> {
         .map(|media| media.matches())
 }
 
-pub fn is_visible(window: &web_sys::Window) -> bool {
-    let document = window.document().expect("Failed to obtain document");
+pub fn is_visible(document: &Document) -> bool {
     document.visibility_state() == VisibilityState::Visible
 }
 
diff --git a/src/platform_impl/web/web_sys/resize_scaling.rs b/src/platform_impl/web/web_sys/resize_scaling.rs
index d80f94a8..8ecd1bd5 100644
--- a/src/platform_impl/web/web_sys/resize_scaling.rs
+++ b/src/platform_impl/web/web_sys/resize_scaling.rs
@@ -3,8 +3,9 @@ use once_cell::unsync::Lazy;
 use wasm_bindgen::prelude::{wasm_bindgen, Closure};
 use wasm_bindgen::{JsCast, JsValue};
 use web_sys::{
-    HtmlCanvasElement, MediaQueryList, ResizeObserver, ResizeObserverBoxOptions,
-    ResizeObserverEntry, ResizeObserverOptions, ResizeObserverSize, Window,
+    CssStyleDeclaration, Document, HtmlCanvasElement, MediaQueryList, ResizeObserver,
+    ResizeObserverBoxOptions, ResizeObserverEntry, ResizeObserverOptions, ResizeObserverSize,
+    Window,
 };
 
 use crate::dpi::{LogicalSize, PhysicalSize};
@@ -20,7 +21,9 @@ pub struct ResizeScaleHandle(Rc<RefCell<ResizeScaleInternal>>);
 impl ResizeScaleHandle {
     pub(crate) fn new<S, R>(
         window: Window,
+        document: Document,
         canvas: HtmlCanvasElement,
+        style: CssStyleDeclaration,
         scale_handler: S,
         resize_handler: R,
     ) -> Self
@@ -30,7 +33,9 @@ impl ResizeScaleHandle {
     {
         Self(ResizeScaleInternal::new(
             window,
+            document,
             canvas,
+            style,
             scale_handler,
             resize_handler,
         ))
@@ -45,7 +50,9 @@ impl ResizeScaleHandle {
 /// changes of the `devicePixelRatio`.
 struct ResizeScaleInternal {
     window: Window,
+    document: Document,
     canvas: HtmlCanvasElement,
+    style: CssStyleDeclaration,
     mql: MediaQueryListHandle,
     observer: ResizeObserver,
     _observer_closure: Closure<dyn FnMut(Array, ResizeObserver)>,
@@ -57,7 +64,9 @@ struct ResizeScaleInternal {
 impl ResizeScaleInternal {
     fn new<S, R>(
         window: Window,
+        document: Document,
         canvas: HtmlCanvasElement,
+        style: CssStyleDeclaration,
         scale_handler: S,
         resize_handler: R,
     ) -> Rc<RefCell<Self>>
@@ -80,7 +89,7 @@ impl ResizeScaleInternal {
                 if let Some(rc_self) = weak_self.upgrade() {
                     let mut this = rc_self.borrow_mut();
 
-                    let size = Self::process_entry(&this.window, &this.canvas, entries);
+                    let size = this.process_entry(entries);
 
                     if this.notify_scale.replace(false) {
                         let scale = backend::scale_factor(&this.window);
@@ -94,7 +103,9 @@ impl ResizeScaleInternal {
 
             RefCell::new(Self {
                 window,
+                document,
                 canvas,
+                style,
                 mql,
                 observer,
                 _observer_closure: observer_closure,
@@ -142,17 +153,8 @@ impl ResizeScaleInternal {
     }
 
     fn notify(&mut self) {
-        let style = self
-            .window
-            .get_computed_style(&self.canvas)
-            .expect("Failed to obtain computed style")
-            // this can't fail: we aren't using a pseudo-element
-            .expect("Invalid pseudo-element");
-
-        let document = self.window.document().expect("Failed to obtain document");
-
-        if !document.contains(Some(&self.canvas))
-            || style.get_property_value("display").unwrap() == "none"
+        if !self.document.contains(Some(&self.canvas))
+            || self.style.get_property_value("display").unwrap() == "none"
         {
             let size = PhysicalSize::new(0, 0);
 
@@ -175,19 +177,19 @@ impl ResizeScaleInternal {
         }
 
         let mut size = LogicalSize::new(
-            backend::style_size_property(&style, "width"),
-            backend::style_size_property(&style, "height"),
+            backend::style_size_property(&self.style, "width"),
+            backend::style_size_property(&self.style, "height"),
         );
 
-        if style.get_property_value("box-sizing").unwrap() == "border-box" {
-            size.width -= backend::style_size_property(&style, "border-left-width")
-                + backend::style_size_property(&style, "border-right-width")
-                + backend::style_size_property(&style, "padding-left")
-                + backend::style_size_property(&style, "padding-right");
-            size.height -= backend::style_size_property(&style, "border-top-width")
-                + backend::style_size_property(&style, "border-bottom-width")
-                + backend::style_size_property(&style, "padding-top")
-                + backend::style_size_property(&style, "padding-bottom");
+        if self.style.get_property_value("box-sizing").unwrap() == "border-box" {
+            size.width -= backend::style_size_property(&self.style, "border-left-width")
+                + backend::style_size_property(&self.style, "border-right-width")
+                + backend::style_size_property(&self.style, "padding-left")
+                + backend::style_size_property(&self.style, "padding-right");
+            size.height -= backend::style_size_property(&self.style, "border-top-width")
+                + backend::style_size_property(&self.style, "border-bottom-width")
+                + backend::style_size_property(&self.style, "padding-top")
+                + backend::style_size_property(&self.style, "padding-bottom");
         }
 
         let size = size.to_physical(backend::scale_factor(&self.window));
@@ -229,11 +231,7 @@ impl ResizeScaleInternal {
         this.notify();
     }
 
-    fn process_entry(
-        window: &Window,
-        canvas: &HtmlCanvasElement,
-        entries: Array,
-    ) -> PhysicalSize<u32> {
+    fn process_entry(&self, entries: Array) -> PhysicalSize<u32> {
         let entry: ResizeObserverEntry = entries.get(0).unchecked_into();
 
         // Safari doesn't support `devicePixelContentBoxSize`
@@ -241,7 +239,7 @@ impl ResizeScaleInternal {
             let rect = entry.content_rect();
 
             return LogicalSize::new(rect.width(), rect.height())
-                .to_physical(backend::scale_factor(window));
+                .to_physical(backend::scale_factor(&self.window));
         }
 
         let entry: ResizeObserverSize = entry
@@ -249,13 +247,8 @@ impl ResizeScaleInternal {
             .get(0)
             .unchecked_into();
 
-        let style = window
-            .get_computed_style(canvas)
-            .expect("Failed to get computed style of canvas")
-            // this can only be empty if we provided an invalid `pseudoElt`
-            .expect("`getComputedStyle` can not be empty");
-
-        let writing_mode = style
+        let writing_mode = self
+            .style
             .get_property_value("writing-mode")
             .expect("`writing-mode` is a valid CSS property");
 
diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs
index eb7ad858..805126ef 100644
--- a/src/platform_impl/web/window.rs
+++ b/src/platform_impl/web/window.rs
@@ -7,7 +7,7 @@ use crate::window::{
 };
 
 use raw_window_handle::{RawDisplayHandle, RawWindowHandle, WebDisplayHandle, WebWindowHandle};
-use web_sys::HtmlCanvasElement;
+use web_sys::{CssStyleDeclaration, Document, HtmlCanvasElement};
 
 use super::r#async::Dispatcher;
 use super::{backend, monitor::MonitorHandle, EventLoopWindowTarget, Fullscreen};
@@ -27,6 +27,8 @@ pub struct Window {
 
 pub struct Inner {
     pub window: web_sys::Window,
+    document: Document,
+    style: CssStyleDeclaration,
     canvas: Rc<RefCell<backend::Canvas>>,
     previous_pointer: RefCell<&'static str>,
     register_redraw_request: Box<dyn Fn()>,
@@ -46,7 +48,10 @@ impl Window {
         let prevent_default = platform_attr.prevent_default;
 
         let window = target.runner.window();
-        let canvas = backend::Canvas::create(id, window.clone(), &attr, platform_attr)?;
+        let document = target.runner.document();
+        let canvas =
+            backend::Canvas::create(id, window.clone(), document.clone(), &attr, platform_attr)?;
+        let style = canvas.style().clone();
         let canvas = Rc::new(RefCell::new(canvas));
 
         let register_redraw_request = Box::new(move || runner.request_redraw(RootWI(id)));
@@ -62,6 +67,8 @@ impl Window {
             has_focus,
             inner: Dispatcher::new(Inner {
                 window: window.clone(),
+                document: document.clone(),
+                style,
                 canvas,
                 previous_pointer: RefCell::new("auto"),
                 register_redraw_request,
@@ -130,24 +137,16 @@ impl Window {
             let mut position = position.to_logical::<f64>(inner.scale_factor());
 
             let canvas = inner.canvas.borrow();
-            let document = inner.window.document().expect("Failed to obtain document");
 
-            if document.contains(Some(canvas.raw())) {
-                let style = inner
-                    .window
-                    .get_computed_style(canvas.raw())
-                    .expect("Failed to obtain computed style")
-                    // this can't fail: we aren't using a pseudo-element
-                    .expect("Invalid pseudo-element");
-
-                if style.get_property_value("display").unwrap() != "none" {
-                    position.x -= backend::style_size_property(&style, "margin-left")
-                        + backend::style_size_property(&style, "border-left-width")
-                        + backend::style_size_property(&style, "padding-left");
-                    position.y -= backend::style_size_property(&style, "margin-top")
-                        + backend::style_size_property(&style, "border-top-width")
-                        + backend::style_size_property(&style, "padding-top");
-                }
+            if inner.document.contains(Some(canvas.raw()))
+                && inner.style.get_property_value("display").unwrap() != "none"
+            {
+                position.x -= backend::style_size_property(&inner.style, "margin-left")
+                    + backend::style_size_property(&inner.style, "border-left-width")
+                    + backend::style_size_property(&inner.style, "padding-left");
+                position.y -= backend::style_size_property(&inner.style, "margin-top")
+                    + backend::style_size_property(&inner.style, "border-top-width")
+                    + backend::style_size_property(&inner.style, "padding-top");
             }
 
             canvas.set_attribute("position", "fixed");
@@ -172,7 +171,7 @@ impl Window {
         self.inner.dispatch(move |inner| {
             let size = size.to_logical(inner.scale_factor());
             let canvas = inner.canvas.borrow();
-            backend::set_canvas_size(canvas.window(), canvas.raw(), size);
+            backend::set_canvas_size(canvas.document(), canvas.raw(), canvas.style(), size);
         });
 
         None
@@ -324,7 +323,7 @@ impl Window {
             if fullscreen.is_some() {
                 inner.canvas.borrow().request_fullscreen();
             } else if inner.canvas.borrow().is_fullscreen() {
-                backend::exit_fullscreen(&inner.window);
+                backend::exit_fullscreen(&inner.document);
             }
         });
     }