Dragging content of overflow div scrolls in both Safari and Firefox, not in Chrome

Viewed 633

I am trying to create custom ui using HTML canvas, but I want to preserve native scrolling behaviour. I came out with a hack, where I overlay my canvas with empty transparent div and repaint canvas depending on scroll position of the div. This works perfectly, except when trying to allow the user to select something painted in the canvas. Usually, you'd expect the element to scroll, which happens in both Safari and Firefox, but not so in Chrome.

Imagine following HTML code:

.container {
  width: 100px;
  height: 100px;
  overflow: auto;
  margin-bottom: 20px;
  border: 2px solid black;
}

.content {
width: 1000px;
height: 1000px;
background: rgb(34,193,195);
background: radial-gradient(circle, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%);
}

.item {
border: 1px solid blue;
width: 50px;
height: 50px;
}
<div class="container">
  <div class="content"></div>
</div>

<div class="container">
  <div class="content">
    <div class="item"></div>
    <div class="item"></div>
  </div>
</div>

This will create two containers with scrollable content inside. Try to click and drag mouse button in both of them as if you were trying to select some invisible text inside. In Safari and Firefox, both containers will scroll. In Chrome, only the second one (containing inner .item divs) will scroll.

Video of dragging in Chrome

Is there a way to get desired behaviour in Chrome? I want to avoid creating huge (thousands) number of DOM elements.

1 Answers

Well for some reason Chrome expects some content to be in it for selection to work, unlike firefox.

You can mock the desired behaviour by having some text within your content div and setting its opacity to 0. Also use the CSS user-select: all; to select the whole text on the first click.

Note: The scroll only works when the cursor is within the bounds of the container (in chrome).

.container {
  width: 100px;
  height: 100px;
  overflow: auto;
  margin-bottom: 20px;
  border: 2px solid black;
}

.content {
  width: 1000px;
  height: 1000px;
  background: rgb(34, 193, 195);
  background: radial-gradient(circle, rgba(34, 193, 195, 1) 0%, rgba(253, 187, 45, 1) 100%);
  user-select: all;
}

.content span{
  opacity: 0;
}

.item {
  border: 1px solid blue;
  width: 50px;
  height: 50px;
}
<div class="container">
  <div class="content"><span>a</span></div>
</div>

<div class="container">
  <div class="content">
    <div class="item"></div>
    <div class="item"></div>
  </div>
</div>

Related