So I'm working on a react app and I basically want to include a scroll bar for smaller window sizes such as a mobile device. So a scroll bar would if and only if the window size is smaller than the menu itself.
What I have so far as a hacky fix.
const styles = {
dropdownContentClass: {
maxHeight: "15 em",
overflowY: "auto",
}
}
Here I force a max height on the menu so its always scrollable but I would like to have a scroll available if a user is on mobile or the window size is relatively small.
EDIT:
var mq = window.matchMedia("(max-width: 768px)")
if (mq.matches){
var mh = "15em"
var oy = "scroll"
}
return {maxHeight: mh, overflowY: oy}
So I got it to work this this sort of hacky fix. Still kind of new to Javascript but its pretty hard to confirm your code when theres millions of ways to do something.
The browser will have scrollbars by default if the content exceeds the height of the window, so this should already work. If you have a container that has a fixed height that's wrapping your page, like one that's absolutely positioned, you'll need to add overflow-y: auto to it as well.
You can wrap everything into a media query which will apply from smaller devices such as mobiles, up to a maximum width you want the scrollbar to stop being displayed.
Example :
#media (max-width: 768px) {
dropdownContentClass: {
maxHeight: "15 em",
overflowY: "scroll",
}
}
This way, your little workaround will only apply for devices with a maximum of 768px, on tablets or desktops will stop
Related
I would like to achieve the following:
On a mobile device, when someone starts scrolling from the top, a text starts to shrink down, and after a given amount, it takes its final size and stays like so for the rest of the page. The idea is that I have a Company name in the middle of the screen, and on scroll, it shrinks to the top left corner of the screen, and a menu bar appears behind it, and the Company name becomes the logo on the menu bar. The menu bar's background is the Hero image of the page. Here is my code:
window.onscroll = scrolled
function scrolled(){
let fromTop = window.scrollY
if (fromTop < 300) {
heroText.style.fontSize = `${2 - fromTop/160}em`
hero.classList.remove('hero-fixed')
heroNav.classList.remove('hero-nav-fixed')
heroText.classList.remove('h1-fixed')
heroImg.classList.remove('hero-img-fixed')
} else {
hero.classList.add('hero-fixed')
heroNav.classList.add('hero-nav-fixed')
heroText.classList.add('h1-fixed')
heroImg.classList.add('hero-img-fixed')
}
if (fromTop > 360) {
heroNav.classList.add('nav-mobile', 'hidden')
intro.classList.add('intro-fixed')
hamburger.classList.remove('hidden')
} else {
hamburger.classList.add('hidden')
heroNav.classList.remove('nav-mobile','hidden')
intro.classList.remove('intro-fixed')
}
}
}
It works, but I have to adjust for every screen size I want to support, and it is extremely laggy! It is probably a very wrong way to do it, so could someone help me make it more efficient and less laggy on mobile devices?
My guess is that the constant resizing of the text is one of the problems, as well as the height change of the hero image. I play with position fixed, and padding-top changes in the CSS to compensate the disappearing (becoming fixed positioned) elements.
Could some library, like RxJS help, or is there a VanillaJS elegant solution as well?
To make this more efficient in the Javascript side, you could use something like lodash's debounce.
Changing layout can be a very resource intensive operation so you might want to try leaving the element fixed position all the time and only adjusting its size (and/or the size of its parents) with the CSS transform property. scale() would work quite nicely here.
I have this following demo website: http://woohooo.fortleet.com/
Pieces of content as well as navigation are set to 100% height. When I'm on my phone, there's this url bar up top that hides when I scroll up. However, this effect messes the 100% height up because it adjusts to the new browser size, creating an unpleasing effect. The same goes for 'vh' and 'vw' units.
I've tried the following:
function windowDimensions() {
if (html.hasClass('touch')) {
height = window.screen.height;
width = window.screen.width;
} else {
height = win.height();
width = win.width();
}
}
function screenFix() {
if (html.hasClass('touch')) {
touch = true;
nav.css({'height' : height + 'px'});
home.css({'height' : height + 'px'});
header.css({'height' : height/2 + 'px'});
content.css({'min-height' : height + 'px'});
}
}
This, however, creates a problem, because at the VERY TOP there's this bar with battery, wifi, signal info that is also accounted to the screen height, making the '100%' and 'vh' elements a tad bigger.
I couldn't believe I didn't find any other question about this, as I assumed this is a pretty common problem for 100%/100% sites.
Do you guys know any fix for this?
Your viewport meta tag seems fine. 100vh will not take into account the menu/wifi/top bar. It will only provide the viewport height, which does not account for the menubar on phones. It's important to note that 100vh, and 100% are not going to be the same height. I took a look at your site in mobile and on desktop, each section appears to be 100vh without any additional padding (so it looks correct to me).
If you are referring to the "iPhone" URL bar that automatically toggles in and out when scrolling, then you won't have any way to hide or toggle that display. The URL bar shows up when you scroll up... so yes... it may mean that you will have 20px or so that will not be visible when the user is scrolling upwards. However, it's usually not a problem, because when you are scrolling downwards IOS hides that bar... as to not affect the view of the screen. This may not answer your question, but the URL bar is what I assumed you meant.
It sounds as if your viewport isn't properly set. I'm pretty sure it should not take that extra 10 - 20 pixels into account.
If you haven't already, try setting the view port meta and disabling all zooming options. Hope this helps :)
Ref: https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag
I'm, setting up the mobile side of a website at the moment, and I need custom CSS and Javascript for mobile, so in the CSS I have rules using #media screen and (max-width: 500px) { and in Javascript I was going to use if ($(window).width() < 500.
However, if I resize my browser to the exact pixel the mobile CSS starts being used and I console.log($(window).width()); I get 485.
Is this normal behaviour or am I doing something wrong?
Update:
Using this, the values seem to be in sync, only tested in firefox though at the moment.
var scrollBarWidth = false;
function mobileRules() {
if (!scrollBarWidth) {
var widthWithScrollBars = $(window).width();
$('body').css('overflow', 'hidden');
var widthNoScrollBars = $(window).width();
$('body').css('overflow', 'scroll');
scrollBarWidth = widthNoScrollBars - widthWithScrollBars;
console.log('Width: '+widthWithScrollBars+'. Without: '+widthNoScrollBars+'. Scroll: '+scrollBarWidth);
}
console.log($(window).width()+scrollBarWidth+' vs '+globals.mobile_width);
if ($(window).width()+scrollBarWidth < globals.mobile_width) {
console.log('Running mobile rules in jQuery');
}
}
In firefox, media queries consider the width of the scrollbar to be inside the screen width.
This is what gives you the 15px wider screen width.
In webkit based browsers they don't.
If you're interested in why this thing happens, I'll quote this comment of this article :
A problem with Webkit browsers (that aren't following spec) is that the browser can encounter an infinite loop condition caused by media queries, which leads to a browser crash.
For example: >500px overflow-y: scroll, <500px overflow-y: hidden. Size your browser to 505px window width. Since the scroll bar subtracts 15 or so pixels from the width used by the media query, the media query flips you to < 500, but as soon as you hit <500 the scrollbar goes away, and the media query flips you to >500, and then the fun starts because now you have a scroll bar again and you're <500px and you get that style with no scroll bar... Rinse and repeat until the browser finally dies.
Now, write some javascript to calculate the media query max widths, and you have a page that will crash Chrome/Safari as soon as you load it.
My guess is that the spec was written the way it was to prevent this condition. Firefox & Opera are following spec, it's not really their fault you don't agree with spec.
I have an .swf navigation carousel that is 650 pixels high, the bottom 200 pixels being reserved for the reflection of the carousel. The reflection is very subtle and is not considered important information, so we would like to remove vertical scrollbars when the window is high enough to fit the topmost 450 pixels, but not the reflection.
I tried to accomplish this by setting a margin-bottom: -200px to the flash <object> but this only made the container's height shrink 200 pixels, causing the background pattern to cut before the bottom of the page. The Flash itself is still taking up 650 pixels.
Is there some "proper" fix to this, other than hiding/showing the scrollbars actively using javascript?
You could try using css:
#idOfElement {
overflow-x: hidden;
overflow-y: hidden;
}
My apologies, I thought you were trying to remove scrollbars from the element. If you want to get them off of the window, just do body {overflow: hidden}
Parts of the element will only get cut off when you do overflow: hidden if the content of the element is larger than its container, so you may want to look into that.
Try this to hide the overflow when the window height reaches 450px:
window.onresize = function () {
var height = window.innerHeight;
if (height > 450) {
document.body.style.overflow = "hidden";
}
}
An issue you may have with this is that some browsers like to fire a lot of resize events during resizing, instead of one after, which could impact performance. Paul Irish wrote a short blog post about mitigating this at http://paulirish.com/2009/throttled-smartresize-jquery-event-handler/ and I think that jQuery's .resize() function does this automatically.
After dabbling in Chrome Extensions I've noticed that when the data inside the Page Action gets to a certain point the scroll bars automatically attach themselves to the popup, this I expect. However, instead of pushing the content to the left of the scroll bar it overlays the content causing a horizontal scrollbar to become active. I ended up just adding a check on my data and applying a css class to push the content to the left more to run parallel to the scroll bar and beside it not under it. What is the correct way to handle this besides my hackish solution?
I was wondering this myself too. Currently I just don't put anything important closer than 20px to the right side of a popup and disable horizontal scrollbars:
body {overflow-x:hidden;overflow-y:auto;}
So when a vertical scrollbar appears the content at least doesn't jump.
Perhaps you need to specify a width on the scrollbar.
::-webkit-scrollbar {
width: 42px; //Do not know actual width, but I assume you do
}
I haven't found a way to do this that isn't a hack, but here's the simplest hack I could think of:
<script type="text/javascript">
function tweakWidthForScrollbar() {
var db = document.body;
var scrollBarWidth = db.scrollHeight > db.clientHeight ?
db.clientWidth - db.offsetWidth : 0;
db.style.paddingRight = scrollBarWidth + "px";
}
</script>
...
<body onresize="tweakWidthForScrollbar()">
The idea is to detect whether the vertical scrollbar is in use, and if it is, calculate its width and allocate just enough extra padding for it.