issue with CSS media queries(scrollbar)

前端 未结 7 1443
别那么骄傲
别那么骄傲 2020-11-27 06:28

I am having problem with css media query in Firefox. It works correct in Chrome like I made two DIVs and want a scrollbar. If I decrease the screen size of firefox upto 800p

相关标签:
7条回答
  • 2020-11-27 06:44

    I SOLVED this issue by calling the "mqGenie" javascript in the head of my project.

    Now the widths of my media queries work fine ( with the same value ) on Chrome, Safari, Firefox and IE with or without scroolbars.

    This javascript Adjusts CSS media queries in browsers that include the scrollbar width in the viewport width so they fire at the intended size.

    You can download it from this url:

    http://stowball.github.io/mqGenie/

    0 讨论(0)
  • 2020-11-27 06:46

    Short Answer

    If you do not want to display the scrollbar all the time, wrap your content into <div> elements etc. you can use JavaScript to add a certain value to all media queries when the scrollbar is shown.

    // check whether scrollbar is visible
    var isScrollbarVisible = window.innerWidth > document.documentElement.clientWidth;
    
    // search for media rule
    var mediaRule = document.styleSheets[i].cssRules[j];
    
    // update media rule
    mediaRule.media.mediaText = '..'
    


    Long Answer

    I wrote a small script which you can include on your page. It detects when the window is resized and changes all media queries if needed. The value of the css variable --replace-media-scrollbar is used as the width of the scrollbar or 15px if no value was found. This works for the media queries with, min-width, max-width, height, min-height and max-height even when they are connected using and.

    JavaScript:

    function* visitCssRule(cssRule) {
        // visit imported stylesheet
        if (cssRule.type == cssRule.IMPORT_RULE)
            yield* visitStyleSheet(cssRule.styleSheet);
    
        // yield media rule
        if (cssRule.type == cssRule.MEDIA_RULE)
            yield cssRule;
    }
    
    function* visitStyleSheet(styleSheet) {
        try {
            // visit every rule in the stylesheet
            var cssRules = styleSheet.cssRules;
            for (var i = 0, cssRule; cssRule = cssRules[i]; i++)
                yield* visitCssRule(cssRule);
        } catch (ignored) {}
    }
    
    function* findAllMediaRules() {
        // visit all stylesheets
        var styleSheets = document.styleSheets;
        for (var i = 0, styleSheet; styleSheet = styleSheets[i]; i++)
            yield* visitStyleSheet(styleSheet);
    }
    
    // collect all media rules
    const mediaRules = Array.from(findAllMediaRules());
    
    // read scrollbar width
    var style = getComputedStyle(document.documentElement);
    var scrollbar = style.getPropertyValue('--replace-media-scrollbar') || '15px';
    
    // update media rules
    if (scrollbar != '0px') {
        var oldValue = '0px';
        function updateMediaRulesScrollbar() {
            var newValue = window.innerWidth > document.documentElement.clientWidth ? scrollbar : '0px';
            // if value changed
            if (oldValue != newValue) {
                for (var i = 0, mediaRule; mediaRule = mediaRules[i]; i++) {
                    var regex = RegExp('\\((width|min-width|max-width|height|min-height|max-height): (calc\\([^)]*\\)|[^)]*)\\)', 'g');
                    var replacement = '($1: calc($2 - ' + oldValue + ' + ' + newValue + '))';
                    mediaRule.media.mediaText = mediaRule.media.mediaText.replace(regex, replacement);
                    console.log(mediaRule);
                }
            }
            oldValue = newValue;
        }
        updateMediaRulesScrollbar();
        window.onresize = updateMediaRulesScrollbar;
    }
    

    Optional CSS:

    :root {
      --replace-media-scrollbar: 15px;
    }
    
    0 讨论(0)
  • 2020-11-27 06:50

    Firefox & Webkit based browsers render the scrollbar differently. In Firefox, MediaQuery considered width of scrollbar which is 15px with the screen width, but in Webkit based browsers it's not considered scrollbar with the screen width. So, that's why the floated DIVs are collapsed in Firefox.

    I did some stuff with css may be that's help you. (check this fiddle)

            html {
                /* force scrollbars */
                height: 101%;
            }
            body {
                margin: 0; 
                padding:0; 
                white-space:nowrap; 
            }  
            #box1,
            #box2 {
                display:inline-block;
                width: 400px;
                height: 200px;  
                vertical-align:top;
                white-space:normal;
            }
            #box1 {
                background: #ce0000;
                 margin-right:-5px;
            }
            #box2 {
                background: #8e0000;
            }
    
            @media screen and (max-width: 799px) { 
                body { 
                    white-space:normal; 
                }
                #box1,
                #box2 {
                    width: 300px;
                }
            }
    
    0 讨论(0)
  • 2020-11-27 06:51

    This is peripherally related, but I found a way to detect which media-query the browser is actually using at any given moment, without having to muck around with scrollbar and body widths...

    Basically, define a an absolutely positioned 1-x-1-pixel-sized list somewhere in your body, with a list-item for each media-query condition you want to be "watchable".

    Then in each media-query definition, show/hide the corresponding list-item, and then simply check whether that item is visible from within your script.

    Example:

    <body>
        ...
        <ul id="mediaQueryHelper">
            <li id="desktop"></li>
        </ul>
    </body>
    
    <style type="text/less">
        #mediaQueryHelper {
            position: absolute;
            height: 1px;
            width: 1px;
            visibility: hidden;
            top: -999px;
            left: -999px;
        }
    
        @media screen and (min-width: 481px)
        {
           #desktop { display: inline; }
        }
    
        @media screen and (min-width: 320px) and (max-width: 480px)
        {
           #desktop{ display: none; }
        }
    
    </style>
    
    <script type="text/javascript">
        $(document).ready(function()
        {
            var _desktop = $("#desktop");
    
            $(window).resize(function() {
                console.log("media-query mode: " + _desktop.is(":visible") ? "DESKTOP" : "MOBILE");
            });
        });
    </script>
    
    0 讨论(0)
  • 2020-11-27 06:54

    Play safe!

    My final strategy is added 20px to the media queries and that is my default white space on the layout.

    With one exception: @media (min-width: 320px) At that size a don't leave the 20px white space and include one more rule to solve minor background issues:

    html body {
        min-width: 320px;
       }
    

    20px is the scroll bar default width size.

    FYI: https://www.sitepoint.com/rwd-scrollbars-is-chrome-better/

    0 讨论(0)
  • 2020-11-27 06:55

    Firefox & Opera follows W3C spec which is to include scrollbar width in media queries width (the reason might be to avoid infinite loop as described in a comment here), while Webkit does not (possibly coz they think it makes no sense)

    There is a workaround (I've only tested this on FF), apparently if you force scrollbar to be visible all the time, then the width will now be consistent with Webkit. Here's the code:

    html
    {
       overflow:hidden;
       height:100%;
    }
    body
    {
       position:relative;
       overflow-y:scroll;
       height:100%;
       -webkit-overflow-scrolling:touch; /* So iOS Safari gets the inertia & rubber-band effect */
    }
    

    If you want to apply this to FF & Opera only, you can resort to CSS hacks:

    /* Firefox */
    @-moz-document url-prefix()
    {
        html
        {
            overflow:hidden;
            height:100%;
        }
        body
        {
            position:relative;
            overflow-y:scroll;
            height:100%;
            /*-webkit-overflow-scrolling:touch;*/
        }
    }
    
    /* Opera */
    x:-o-prefocus, html
    {
        overflow:hidden;
        height:100%;
    }
    x:-o-prefocus, body
    {
        position:relative;
        overflow-y:scroll;
        height:100%;
    }
    

    It goes without saying, the caveat is the scrollbar will be visible at all times, which might be an okay compromise.

    0 讨论(0)
提交回复
热议问题