3

I'm making a web app which contains a hidden sidebar which appears by moving in from the right. The most obvious way of achieving this is to hide the sidebar offscreen with overflow: hidden; on the parent element and use css transitions to animate the right property so that it appears when the user presses a button.

However, what I found was that even though overflow: hidden; disables scrollbars, the user is able to scroll the parent element to the sidebar by using Ctrl+F or tabbing to an element on the sidebar while it is supposed to be hidden offscreen, pushing some of the main app offscreen in the process.

Here's a JSFiddle I made to demonstrate the problem.

While this is not a particularly big problem (it can be fixed by just toggling the sidebar again) it is obviously undesirable and I haven't found a good way to deal with it.

I could use javascript to listen for transitionend events to set visibility to hidden on the sidebar so that the text can't be selected when the sidebar is hidden, but the user is still able to do this while the transition is happening and scroll offscreen anyway.

I could also put all the text in pseudoelements and add tabindex="-1" on all the focusable elements so that nothing is selectable, but that seems over the top and also quite messy, doesn't allow the user to Ctrl+F or tab to elements on the sidebar when it is visible, which is undesirable.

I could also have the sidebar appear in from the left instead of the right, but I'd rather see if there's a better way of doing this first than to change the entire design of the app.

Apologies if this has been addressed elsewhere, but I've searched around and not found anything that concerns my problem.

MrInanimated
  • 41
  • 1
  • 4

4 Answers4

5

One solution is to set #Sidebar position to fixed. And also replace right with transform: translateX() to hide/show it.

JSFiddle link

knitevision
  • 2,485
  • 6
  • 24
  • 41
  • Thank you, this works exactly as I intend it to! I still need to add `display: none` or `visibility: hidden` while the sidebar is hidden so users can't select anything on it then though. – MrInanimated Jul 21 '15 at 14:05
  • Same issue working on off-screen side menu. This saved my life! – Nigel Earle Jan 26 '17 at 21:41
0

This is an interesting case which I haven't heard or thought about, that said the 'error' does make sense. I guess the issue is that the text is offscreen and hidden, but still present. I would set that div as display:none and then change this value through your javascript toggle so that the div becomes: display:inline and then pulls out.

Patrick
  • 53
  • 7
0

You could check if the element is outside viewport, then display:none on it.

This question will help check if element is outside viewport.

Community
  • 1
  • 1
0

Use another class that will have properties display: none; -> that way you will not be able to tab to it/ctrl+F it.

CSS:

#Sidebar {
    ...
    display: none;
}
#Sidebar.block {
    display: block;
}

Javascript:

if (sidebar.classList.contains("open")) {
    sidebar.classList.remove("open");
    setTimeout(function() {
        sidebar.classList.remove("block");
    }, 3500); // consider faster transitions!
} else {
    sidebar.classList.add("block");
    setTimeout(function() {
        sidebar.classList.add("open");
    }, 50);
}

Here's the fiddle: https://jsfiddle.net/j9d0e7ug/2/

Note that I use setTimeout(), because otherwise changing display between block and none destroys animations. Also consider faster transitions :)

DekiChan
  • 315
  • 1
  • 5
  • 13
  • Well, I can still scroll the main container off while the transition is proceeding. I guess the way I should do this is to set faster transitions and just not worry about it so much. I'd just like to ask though, is there a difference in `visibility: hidden` and `display: none` in this case? Currently I'm essentially doing that except I use `transitionend` to watch for when the sidebar goes back and setting `visibility: hidden` on it instead of `display: none`. – MrInanimated Jul 21 '15 at 13:43