Почему размер windows меньше ширины видового экрана, заданного в медиа-запросах

Я довольно озадачен и до сих пор не знаю, как это объяснить правильно. До сих пор я использовал и настраивал свои медиа-запросы с помощью Breakpoint. Используемая переменная Breakpoint выглядит так:

$menustatictofixed: min-width 900px; 

Для параметра $ breakpoint-to-ems установлено значение true. Я выложил страницу со всеми ее переменными Breakpoint на основе значений пикселей следующего fragmentа jQuery:

 $('body').append('
Viewport width px
'); var viewportWidth = $(window).width() $('#width').text(viewportWidth); $(window).resize(function() { var viewportWidth = $(window).width(); $('#width').text(viewportWidth); });

Все выглядело правильно и чисто. Но за последний один или два дня у меня были проблемы с настройкой последних точек останова для шаблона и для того, чтобы заставить вещи вести себя предсказуемыми. Каким-то образом вещи, которые, казалось, складывались в чистоту и в порядке, в первую очередь, я логически сильно сомневаюсь сейчас, на самом деле являются ненадлежащими и как-то беспорядочными. Если вы посмотрите на следующий снимок экрана, то как-то ширина windows (в Chrome) отличается шириной от fragmentа jQuery с использованием window.width. Также нет разницы, если бы я заменил window.width на window.innerWidth, чтобы в конечном итоге исключить полосы прокрутки. Единственный способ получить правильные результаты – добавить 15 пикселей к уравнению:

 var viewportWidth = $(window).width() + 15; 

Единственная проблема во всем уравнении, что window.width является неправильным выбором функции, и было бы лучше пойти, например, document.documentElement.clientWidth или что-то еще или …? И для чего стоят 15 пикселей, для которых проблема была решена немного хакерским способом? С наилучшими пожеланиями Ральф

    Ответ – полоса прокрутки, и решение сложно.

    Интересны медиа-запросы. Они не ведут себя точно так же в браузере, то есть использовать их иногда не так просто. Например, в -webkit / -blink для OS X и IE10 на Win8, полосы прокрутки накладываются на страницу. Однако в -moz полосы прокрутки не накладываются на страницу. Лучший способ получить «видимую область» страницы – это следующая строка ванильного JavaScript (при условии, что у вас есть допустимый HTML-документ):

     document.body.parentNode.clientWidth 

    Что это будет делать, так это найти элемент body , найти его родительский элемент (который в действительном документе будет элементом html ), а затем найти его ширину после рендеринга. Это даст вам ширину, которую вы хотите видеть. Это тоже бесполезная ширина .

    Почему вы спрашиваете, имеет ли фактическая ширина клиента бесполезно? Дело не в том, что оно зависит от браузера, а от браузера. Это потому, что это не то, что запросы на width медиа на самом деле тестируются! В тесте width media queries test используется window.innerWidth , который вы сейчас используете.

    Итак, каково решение этой проблемы? Ну, я бы сказал, что решение заключается в использовании медиа-запросов на основе контента, а не на медиа-запросах на основе устройств, и быть в порядке с некоторыми местами для маневра в ваших запросах (особенно, если это пространство для маневра составляет около 15px ). Если вы еще этого не сделали, прочитайте статьи Vexing Viewports и Crash Identity Crisis, чтобы получить представление о том, почему потенциальный 15px мерцание в ваших определениях MQ не является наихудшей вещью в мире (вероятно, есть большая рыба, чтобы жарить) ,

    Итак, в заключение продолжайте использовать $breakpoint-to-ems: true и выберите свои медиа-запросы на основе того, когда контент разбивается на window.innerWidth поскольку это единственный разумный способ обработки проблем с несколькими браузерами. С беглым взглядом на различные проблемы кажется, что большинство браузеров и ОС переходят на панель прокрутки (на Firefox 24 каждый браузер OS X будет один, пользовательский интерфейс Ubuntu Unity представил их ), поэтому, чтобы быть в будущем дружественным , Я бы посоветовал не беспокоиться о смещении полосы прокрутки и быть в порядке с сайтами, которые выглядят немного по-разному в браузере. Помните, как Этан Маркотт так красноречиво поставил:

    Интернет – это нестабильная среда

    Это то, что сработало для меня: CSS-медиа-запросы и ширина windows JavaScript не совпадают .

    Вместо использования $(window).width(); которая включает в себя полосы прокрутки, получает внутреннюю ширину следующим образом:

     function viewport() { var e = window, a = 'inner'; if (!('innerWidth' in window )) { a = 'client'; e = document.documentElement || document.body; } return { width : e[ a+'Width' ] , height : e[ a+'Height' ] }; } var vpWidth = viewport().width; // This should match your media query 

    Это из-за scrollbar's

    Самое правильное решение, которое я нашел, – это использовать медиа-запросы для передачи фактического размера windows в Javascript. Вы должны выполнить следующие действия:

    • Добавьте скрытый элемент на свою страницу,
    • Используйте медиа-запросы, чтобы изменить свойство max-width этого элемента,
    • Считайте свойство max-width этого элемента через Javascript.

    Например, добавьте следующий элемент на свою страницу:

     

    Затем напишите следующие правила CSS:

     #currentMedia { display: none; } @media (max-width: 720px) { // Make arrows in the carousel disappear... #currentMedia { max-width: 720px; } } 

    Затем, со стороны Javascript, вы можете написать:

     if (parseInt(jQuery("#currentMedia").css("max-width"), 10) <= 720) { // Code HERE.. } 

    И это будет точно, независимо от размера полосы прокрутки, поскольку значение исходит из того же медиа-запроса, который вызывает исчезновение карусели.

    Я тестировал это решение во всех основных браузерах, и он дает правильные результаты.

    Вы найдете большое резюме о том, какие свойства поддерживаются в браузерах на этой странице на quirksmode.org .

    Лучше всего, чтобы захватить элемент на странице (используя document.body, где поддерживается, или document.getElementById или что-то еще), пройдите по цепочке offsetParent, чтобы найти самый верхний элемент, а затем проверьте clientWidth этого элемента и clientHeight.

    внутренняя документация

    .innerWidth() не применим к объектам window и document ; для них вместо этого используйте .width() .

    Подобно ответу @ Snugugs, но лучше работал для моего варианта использования:

    CSS (Примечание. Я использую LESS, чтобы @tabletMin и @desktopMin переводили в переменные точки останова, которые я установил в другом месте:

      #cssWidth { display:none; content:'mobile'; } /* Responsive styles (Tablet) */ @media (min-width: @tabletMin) { #cssWidth { content:'tablet'; } /* Other tablet CSS... */ } /* Responsive styles (Desktop) */ @media (min-width: @desktopMin) { #cssWidth { content:'desktop'; } /* Other Desktop CSS... */ } 

    И затем в JS:

      getView = function() { // If #cssWidth element does not exist, create it and prepend it do body if ($('#cssWidth').length === 0) { $('body').prepend($(document.createElement('div')).attr('id', 'cssWidth')); } // Return the value of the elements 'content' property return $('#cssWidth').css('content'); }; 

    Затем функция getView () вернет строку «мобильный», «планшет» или «рабочий стол» в зависимости от ширины запросов к медиа-запросу .

    Это может быть расширено, чтобы соответствовать большей ширине видового экрана, просто добавьте больше правил в CSS с другими значениями.

    Ответ @Snugug дает действительно хорошее объяснение, почему это происходит, и @TusharGupta также имеет хорошее решение, которое ссылается на ширину распознаваемой медиатекста на javascript. Ниже решения идет наоборот, используя ширину, определяемую javascript, чтобы вызвать изменения макета.

    Если вам нужно синхронизировать медиа-запросы с помощью определения ширины пикселя javascript, одним из способов приближения к проблеме является запуск изменений CSS-макета на основе classов, которые вы добавляете с помощью javascript.

    Итак, вместо написания медиазаписей напишите те объявления, вложенные под class, скажем:

     html.myMobileBP { ... } 

    И в javascript / jQuery добавьте этот class:

     if ($(window).width() < myMobileBPPixelSize) { $("html").addClass("myMobileBP"); } 

    Чтобы продвинуть это еще больше, вам может потребоваться отсутствие поддержки javascript. Определите медиа-файлы, которые, кроме того, завернуты в html.no-js , затем с javascript удалите class .no-js и примените вышеупомянутое решение добавления точек останова через classы javascript.

    перейдите по этой ссылке

     function getWindowWidth() { var windowWidth = 0; if (typeof(window.innerWidth) == 'number') { windowWidth = window.innerWidth; } else { if (document.documentElement && document.documentElement.clientWidth) { windowWidth = document.documentElement.clientWidth; } else { if (document.body && document.body.clientWidth) { windowWidth = document.body.clientWidth; } } } return windowWidth; } 

    Используйте classы на теле, чтобы определить, используете ли вы на мобильных устройствах, планшетах или настольных компьютерах вместо пикселов.

    Для меня это не сработало document.body.clientWidth или innerWidth . Моя функциональность падает между 1023-1040px, даже если мой код js должен выполнить эту инструкцию:

     if($(window).width()<1024) 

    Решение заключалось в том, чтобы надеть новый class classа менее 1024 и назвать его «small-res» и использовать его, чем в моем коде вместо проверки пикселей:

     if($(body).hasClass('small-res')) 

    Я тоже рекомендую его вам.

    Давайте будем гением компьютера.