For <html dir="rtl">
some browsers (Safari, Edge, IE) will automatically move the scrollbar to the left side which is the correct behavior:
Unfortunately, major browsers (Chrome and Firefox) are behaving in a different way, the scrollbar is still on the right side of the browser.
Is it possible to detect programmatically (preferably with vanilla JS) on which side is scrollbar?
UPD (28.09.2018): so far, there's no working solution in the answers, people are trying to detect the scrollbar position by using getBoundingClientRect().left
or .offsetLeft
and that will not work because it will always be 0
at least in Edge independently from the scrollbar position.
UPD (15.10.2018): TLDR: there's no way.
It seems that browsers do not provide API for detection the scrollbar side. In answers below there are tricks with insertion of a dummy div
and calculating where is scrollbar in that div. I can not consider those tricks as an answer because the document scrollbar could be positioned with multiple ways (<html dir="rtl">
, RTL version of OS, browser settings, etc.)
To get or set the scroll position of an element, you follow these steps: First, select the element using the selecting methods such as querySelector() . Second, access the scroll position of the element via the scrollLeft and scrollTop properties.
A standard scroll bar is located in the nonclient area of a window. It is created with the window and displayed when the window is displayed.
Using the devtools To find out which elements cause a horizontal scrollbar, you can use the devtools to delete elements one by one until the scrollbar disappears.
You find the height of the scrolling container, then compare that to the scroll position. If they are the same, then you have reached the bottom.
As it is shown here, the scrollbar won't change side with dir="rtl"
on html
or body
HTML tag in Firefox, Chrome, Opera & Safari. It works on IE & Edge. I tried (on Edge 17, IE 11, Firefox 62, Chrome 69, Opera 56, Safari 5.1) and it is still relevant in october 2018 (Safari > 9.1 display scrollbar on left side if dir="rtl"
).
I didn't find any cross browser native solution until now to find the position of the scrollbar as you asked. I don't think you have one. We can only try to find "hack" to fix it...
Based on your question / comments and on your real issue here, i think it would be better to focus on the compatibility of dir="rtl"
. You are trying to find out the position of the scrollbar because it was not working as expected in the first place. To make it work as expected, a quick fix could be to put the scroll on the body
element :
<!DOCTYPE html>
<html dir="rtl">
<head>
<meta charset="utf-8">
<title></title>
<style>
html, body {
height: 100%;
overflow: hidden;
}
body {
padding: 0;
margin: 0;
overflow-y: auto; /* or overflow: auto; */
}
p {
margin: 0;
font-size: 8em;
}
</style>
</head>
<body>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</body>
</html>
This css code will make the body
element to scroll instead of the html
element. Strangly, put the scroll on body
will display the scrollbar at the right place. It works for recent versions of browsers.
The exact compatibility is (oldest working version tested) :
With the browsers which are compatible, you can "trust" the scrollbar position based on the dir
attribute. It means that for browsers listed above, the scrollbar will be on the left for dir="rtl"
and on the right for dir="ltr"
. I tested and it works.
For older browsers versions, i don't have fix for the moment. It means that you won't be fully compatible, but it's mainly a problem with safari as you can see.
EDIT : Research to find the position of the scrollbar
As i mentionned above, i think we can try to find a "hack" to find the position of the scrollbar. I am not a css expert so my solution is not very pretty. Someone with css skills could probably find a good solution.
If the scroll is on the body (solution above), we can detect the scrollbar position with css positioned element. For example this code :
<!DOCTYPE html>
<html dir="rtl">
<head>
<meta charset="utf-8">
<title></title>
<style>
html, body {
height: 100%;
overflow: hidden;
}
body {
padding: 0;
margin: 0;
overflow-y: auto;
}
p {
margin: 0;
font-size: 8em;
}
#sc { position: relative; float: left; }
#sc_2 { position: relative; float: right; }
#sc_3 { position: absolute; width: 100%; }
</style>
</head>
<body>
<div id="sc"></div>
<div id="sc_2"></div>
<div id="sc_3"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<script>
var html = document.getElementsByTagName('html')[0];
var sc = document.getElementById('sc');
var sc_2 = document.getElementById('sc_2');
var sc_3 = document.getElementById('sc_3');
if (sc_2.offsetLeft < html.clientWidth && !(sc_3.offsetLeft < 0)) {
console.log('bar on the right');
} else if (sc.offsetLeft > 0 || sc_3.offsetLeft < 0) {
console.log('bar on the left');
} else {
console.log('no bar');
}
</script>
</body>
</html>
The compatibility is (oldest working version tested):
This solution is not very useful if the scroll is on the body
tag because as mentionned above in this case we can "trust" the dir
attribute. I put it here because it could probably be adapted for the scroll on the html
tag.
I improved on Andre's answer:
All you need is getComputedStyle()
console.clear();
const btn = document.querySelector('Button');
const html = document.querySelector('html');
const wrap = document.querySelector('#myBodyWrapper');
const input = document.querySelector('input');
var state = 'ltr';
var inner = '';
for (var i = 0; i < 500; i++) {
inner += 'Lorem ipsum Bla bla bla<br>';
}
wrap.innerHTML = inner;
btn.addEventListener('click', function() {
toggleDirection(html)
}, false);
function getDirection(elem) {
return window.getComputedStyle(elem).direction
}
function setDirection(elem, direction) {
elem.setAttribute('dir', direction)
}
function toggleDirection(elem) {
if (getDirection(elem) === 'ltr' || getDirection(elem) === undefined) {
setDirection(elem, 'rtl')
} else {
setDirection(elem, 'ltr')
}
input.value = getDirection(elem)
}
input.value = getDirection(html)
body {
margin: 0;
padding: 0;
overflow: hidden;
text-align: center;
}
div#myBodyWrapper {
overflow: auto;
height: 80vh;
text-align: start;
margin: 10px 40px;
padding: 10px;
background-color: goldenrod;
}
button {
background-color:gold;
padding:5px;
margin:5px 0;
}
input {
background-color: silver;
text-align: center;
padding: 5px;
font-size: 20px;
}
<button>Switch scrollbar</button><br>
<input type="text" value="">
<div id="myBodyWrapper"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With