diff --git a/component/ElementCall.module.css b/component/ElementCall.module.css index 461ad9b0c..f99dccb16 100644 --- a/component/ElementCall.module.css +++ b/component/ElementCall.module.css @@ -6,15 +6,26 @@ Please see LICENSE in the repository root for full details. */ /* The container a host mounts us into. It fills whatever space the host gives -it, and establishes a stacking context of its own so that our overlays and -modals cannot escape it — which is the whole reason for embedding rather than -using an iframe. */ +it, and nothing we draw may leave it. + +That takes two separate things, which are easy to mistake for one. `isolation` +gives us a stacking context, so nothing inside can be layered above the host's +own interface. Containment makes us the containing block for `position: fixed` +descendants, and clips what we paint to our own box: without it, the modal +scrim and dialog — which are positioned `fixed` and centred, since in the app +they are meant to cover the page — resolve against the viewport and appear in +the middle of the host's window rather than in the middle of the call. + +The clipping cuts both ways: a menu near the edge of a small container is +trimmed rather than overflowing into the host. That is the trade being an +embedded component makes. */ .root { display: flex; flex-direction: column; inline-size: 100%; block-size: 100%; isolation: isolate; + contain: layout paint; position: relative; background-color: var(--cpd-color-bg-canvas-default); color: var(--cpd-color-text-primary); diff --git a/src/button/ReactionToggleButton.module.css b/src/button/ReactionToggleButton.module.css index 90c6af021..705d4d9ed 100644 --- a/src/button/ReactionToggleButton.module.css +++ b/src/button/ReactionToggleButton.module.css @@ -19,7 +19,12 @@ } div.reactionPopupMenuRoot.reactionPopupMenuModal { - --overlay-top: 82vh; + /* Down near the footer it belongs to, rather than centred like other modals. + A percentage, not a viewport unit: the overlay is positioned `fixed`, so this + resolves against the page in the standalone app and against the container + when a host embeds us — where 82vh would put it below the container + entirely. */ + --overlay-top: 82%; width: fit-content; } diff --git a/src/room/ReactionsOverlay.module.css b/src/room/ReactionsOverlay.module.css index 3738dc09e..618adbf38 100644 --- a/src/room/ReactionsOverlay.module.css +++ b/src/room/ReactionsOverlay.module.css @@ -3,8 +3,11 @@ display: inline; z-index: 2; pointer-events: none; - width: 100vw; - height: 100vh; + /* Percentages, not viewport units: the containing block is the element + Element Call treats as its root, which is the page in the standalone app but + the container a host gave us when embedded. */ + width: 100%; + height: 100%; left: 0; top: 0; } @@ -16,7 +19,7 @@ animation-name: reaction-up; width: fit-content; position: relative; - top: 80vh; + top: 80%; } @keyframes reaction-up { @@ -24,7 +27,7 @@ opacity: 1; translate: 0 0; scale: 200%; - top: 80vh; + top: 80%; } to { @@ -48,7 +51,7 @@ .reaction { font-size: 48pt; animation-name: reaction-up-reduced; - top: calc(-50vh + (48pt / 2)); - left: calc(50vw - (48pt / 2)) !important; + top: calc(-50% + (48pt / 2)); + left: calc(50% - (48pt / 2)) !important; } }