There seems to be an issue with the accurate calculation of the screen width while utilizing the scrollbar-gutter

Please take note: The scrollbar-gutter: stable; property is not compatible with Safari. Additionally, the issue seems to be specific to Chrome and works fine in Firefox.

I have observed some unusual behavior when attempting to position elements fixed to the viewport with the use of scrollbar-gutter: stable.

Normally, when there is a scrollbar or a stable scrollbar gutter, the full screen width should adjust to accommodate the scrollbar/gutter by subtracting its width. This ensures that setting right: 0; does not place the element behind the scrollbar but rather aligns it correctly.

However, in the code snippet provided below, the width calculation appears to disregard the gutter, resulting in the red div being misaligned and the yellow div appearing behind the scrollbar, partially obscuring the text.

The snippet includes a feature where clicking on the screen logs the width of the div. Initially, the correct width considering the gutter is displayed. Strangely, upon a second click, the width inexplicably changes to an incorrect value. What could be causing this issue and how can it be rectified?

const test = document.querySelector(".container");

document.addEventListener("click", () => console.log(test.clientWidth))
html {
  scrollbar-gutter: stable;
}
.container {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: skyblue;
}
.test1 {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 10rem;
  height: 10rem;
  background: salmon;
}
.test2 {
  position: fixed;
  right: 0;
  top: 0;
  height: 50%;
  width: 4.5rem;
  background: yellow;
}
<div class="container">
  <div class="test1"></div>
  <div class="test2>Some text example</div>
</div>

Answer №1

Discovering a bug has been reported in Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=1251856 ("Issue 1251856: Elements with position: fixed should respect scrollbar-gutter: stable" from September 2021, still unresolved as of January 2024).

Depending on the specific situation, there are potential workarounds available. Utilizing width: 100vw; consistently appears to yield the same results. Therefore, employing position: fixed; left: 50vw; prevents unnecessary jumping. Additionally,

left: 100%; transform: translateX(-100%);
effectively positions an element on the left side of the stable gutter/the scrollbar. (However, avoid dynamically applying overflow: hidden to html, as this can trigger the bug once more.

I have yet to explore JavaScript solutions, but it might be possible to extract positions from a concealed element to achieve the desired outcome.

Answer №2

Given the HTML provided, you can achieve the desired layout by using a grid system. The salmon block can be centered by placing it in the "center" of a grid with an automatic row span of 5, while the yellow block can be placed in the first 2 out of 4 specified grid rows.

I have removed fixed placements and relied on the view to determine size.

To enhance the layout, I added two elements that are positioned as a large '+' within the container.

The body utilizes a grid for positioning, and the salmon/yellow blocks are placed within the container grid as well.

With these adjustments, the salmon block (and '+') will remain at the center of the grid using the automatic row span of 5, while the yellow block will occupy the top right two grid rows out of 4.

Resize the screen to full size and adjust the height to display the scroll bar correctly. You will notice the scroll appears over the padding on the yellow block without covering the text.

This layout is optimized for modern CSS techniques and should work effectively for your requirements.

const container = document.querySelector(".container");

document.querySelector('.test1').addEventListener("click", (event) => {
  event.currentTarget.textContent = document.body.clientWidth + ' | ' + container.clientWidth;
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-size: 16px;
}

body {
  width: 100vw;
  height: 100vh;
  display: grid;
  place-items: center;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-columns: 1fr 1fr 1fr;
}

.container {
  scrollbar-gutter: stable;
  grid-row: 1 / 2;
  grid-column: 1 / 2;
  width: 100vw;
  height: 100vh;
  display: grid;
  grid-template-columns: 4.5em 1fr 4.5em;
  grid-template-rows: 1fr 1fr 1fr 1fr;
  align-items: center;
  justify-content: center;
  background: skyblue;
}

.test1 {
  grid-column: 2;
  grid-row: 1 / 5;
  align-self: center;
  justify-self: center;
  width: 10em;
  height: 10em;
  background: salmon;
}

.test2 {
  grid-row: 1 / 3;
  grid-column: 3;
  height: 50vh;
  width: 4.5em;
  background: yellow;
  padding-right: 1em;
}

.hori {
  grid-row: 1;
  grid-column: 1;
  width: 75vw;
  border: 1px solid blue;
  height: 1px;
  z-index: 100;
}

.vert {
  grid-row: 1;
  grid-column: 1;
  height: 75vh;
  border: 1px solid lime;
  width: 1px;
  z-index: 101;
}
<div class="container">
  <div class="test1"></div>
  <div class="test2">Some text example</div>
</div>
<div class="hori">
</div>
<div class="vert">
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The most effective way to transmit data from an asynchronous call in Node.js while ensuring a reliable fallback routing structure

I have a request function that makes a call to an endpoint and retrieves data from it. When passing this data to an hbs template for rendering, the array is empty due to asynchronicity. Can someone guide me on the correct approach? Below is the code snippe ...

E/AndroidRuntime: CRITICAL ERROR: main --- java code in an android app

I've been working on a map application and I've run into some issues. Can anyone help me figure out what's wrong with my code? ERROR 10-25 01:37:41.296 28673-28673/com.onemap.activities E/AndroidRuntime: FATAL EXCEPTION: main 10-25 01:37:4 ...

Fetching dynamic JavaScript generated by PHP

I am creating a lightweight website and I have a piece of javascript code that I want to convert into a module by putting it in a separate file. This way, the code will only be loaded after a specific onClick event occurs. Successfully loading the javascr ...

Difficulties encountered with CSS transitions when using the background

I stumbled upon some interesting examples on Stack Overflow about the fade effect on link hover. Curious, I decided to try it out myself and created this JSFiddle. <div class="fade"/> .fade { -o-transition: 0.3s; -moz-transition: 0.3s; -khtml-tran ...

Is your Facebook send button appearing strangely? Find out how to fix it here!

I recently integrated the Facebook send button on my website, allowing users to easily share information about each drive listed. However, a new issue has arisen where clicking on the send button opens a popup inside a table, negatively affecting the page& ...

What is the process for assigning a regular expression to an object?

As I work on editing a configuration file, I'm encountering some issues where things aren't quite functioning as expected. Below is the code snippet I am working with: config.module.rules.unshift( { test: "/ckeditor5-[^/\\ ...

The Ajax GIF Loader is not functioning in the latest versions of Internet Explorer and Firefox, but it is running smoothly in

The animated GIF loader functions correctly in the latest version of Chrome, but does not animate when viewed in IE and Firefox. Below is the code snippet: $("#DIALOG").dialog({ buttons : { "Yes" : function() { ...

Sharing data between AngularJS and D3 with JSON - a guide

When working on my application controller, I typically send a request to my API. This is what it usually looks like: .state('state1', { url: '/datas/:id', templateUrl: 'myurl.com', title: 'title', ...

The keyup event fails to trigger for the search input in datatables when ajax is being used

When loading a page with a jQuery datatable via AJAX, I am aiming to implement custom filtering when the user starts typing in the default filter provided by datatables. The custom logic needs to be applied when the keyup event is triggered. Since AJAX is ...

The Vuetify navigation drawer seems to have a quirk where it only closes after an item

I am brand new to Vue and struggling to figure out why my vue v-navigation-drawer is not working properly. It is located in app-root.vue and was initially closing when clicking on a drawer item, but now requires two clicks to close. After the first click, ...

Activated a DOM element that was retrieved through an AJAX request and displayed it inside a light

I want to implement a lightbox plugin (specifically lightbox_me) to display a html DOM element retrieved through an ajax request. This is the code I am using: <script src="script/jquery.lightbox_me.js"></script> <script> $(& ...

Obtain the data from a nested array

I'm facing a situation where I have the following code: var obj = { level1 : { level2 : 'value' } }; I also have another object: var returnData = { value: "level1.level2", anotherThing: "level1" }; The goal is to ...

The fetch request in a React application is not returning a response body, whereas the same request functions properly when made using Postman

My React app is successfully running locally with backend REST APIs also running locally. However, when I attempt to make a POST call to the REST API, the call goes through but the body appears to be empty. Below is a snippet of the sample code: const bod ...

Is it possible to eliminate the black bars from YouTube HQdefault image using only CSS?

(After searching extensively, I couldn't find the exact same question and answer) I have a dilemma with displaying YouTube's hqdefault thumbnails on my page. It seems that they are 480 by 360 pixels, resulting in black bars at the top and bottom ...

Utilizing deferred to ensure that one function completes before triggering a refresh

In my JavaScript code, I have an ajax call that receives a GUID from the server-side code in the response. After getting the GUID successfully, it is used to make a call to an iframe. The ultimate goal is to refresh the page once the iframe has completed i ...

Encountered a cross-domain error with node.js and jQuery: ERR_CONNECTION_REFUSED

Just beginning my journey with Node.js. I've set up a basic node/express application that serves a single webpage featuring a button. When clicked, this button triggers a jQuery ajax request to an Express route. The route callback then makes an http ...

The readyState of Ajax is consistently anything but 4

I have encountered an issue with my JavaScript code. I am running these codes in order to display data based on user input. Despite there being no error connection and the connection happening properly, whenever I enter a name it always goes into the else ...

Interrupt the current with an external factor

I am working with a flexbox layout that currently looks like this: https://i.stack.imgur.com/ULHEk.jpg My main question now is whether there is a way to disrupt the flow externally from the flexbox, so that the blocked element can move to the next positi ...

Using Electron to Show a Video Stored in the Local File System Using a Custom Protocol

Currently, I'm facing challenges while using electron to develop a basic video display application. Despite my efforts, I am struggling to show a video in the renderer by correctly implementing the registerSchemesAsPrivileged method. Although there ar ...

Arrange a collection of objects based on various nested properties

I am faced with the challenge of managing an array of objects representing different tasks, each categorized by primary and secondary categories. let tasks = [ { id: 1, name: 'Cleanup desk', primary_category: { id: 1, na ...