Есть ли способ определить, имеет ли браузер точность субпикселя?

Есть ли способ определить, имеет ли браузер точность субпикселя для элементов?

IE9, в отличие от любого другого основного браузера, имеет субпиксельную точность для своих элементов (ширина элементов может быть 50.25px), и из-за этого мне нужно обрабатывать вещи по-другому.

Один из способов - использовать jQuery для определения имени и версии браузера, но это не рекомендуется в jQuery и не рекомендуется, вместо этого предлагается, чтобы существование функций проверялось не на имена и версии браузеров.

Ответ 1

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

Из раздел 4.3 спецификации (выделено мной):

Формат значения длины (обозначается как <length> в этой спецификации) является <number> (с десятичной точкой или без нее), за которым следует единичный идентификатор (например, px, em и т.д.).

И определение <number> :

Некоторые типы значений могут иметь целочисленные значения (обозначаемые символом <integer> ) или значения действительного числа (обозначаемые <number> ). Реальные числа и целые числа указаны только в десятичной нотации. < целое > состоит из одной или нескольких цифр от "0" до "9". A < число > может быть как <integer> , или может быть нулем или более цифрами, за которым следует точка (.), за которой следует одна или несколько цифр. И целям, и действительным числам может предшествовать знак "-" или "+", чтобы указать знак. -0 эквивалентно 0 и не является отрицательным числом.

Следовательно, для спецификации единица длины px должна поддерживать дробные числа.

Чтобы доказать это, взгляните на эту скрипту в fullscreen и используйте функцию масштабирования вашего браузера для увеличения масштаба изображения:

Fiddle screenshot

В этом скриншоте Chrome обратите внимание, что синяя коробка размером 5.5px действительно выше, чем красная рамка 5px.


Я думаю, что путаница может возникнуть из-за того, что нестандартный element.clientHeight возвращает вычисленное (округленное) целочисленное значение и что округление происходит по-разному в разных браузерах.

В моей скрипке для clientHeight синего <div>, IE9 и Firefox 15 при 100% масштабировании дают 6. Chrome 22 и Opera 12 дают 5. Во всех браузерах значение этого свойства изменяется, когда пользователь меняет уровень масштабирования браузера.

Другими словами, он ненадежный.

Если вы хотите выполнять вычисления с фактическими, дробными единицами элемента, используйте getComputedStyle.

var el = $('#b')[0]; // the actual DOM element
var height = parseFloat(getComputedStyle(el).height); // => 5.5

Ответ 2

Вы можете создать контейнер с нечетным размером и отбросить в нем два 50% -ных элементов ширины и выяснить, были ли они разделены на 50:50 или нет.

См. http://jsfiddle.net/alnitak/jzrQ6/

Он возвращает false в Chrome 22.0.1229.79 на MacOS X 10.8.2 и true в Firefox 15.0.1. У меня нет MSIE для тестирования.

Ответ 3

http://jsfiddle.net/KAW3d/1/

  • в IE6, IE7 и Opera 12.02: 100.5px + 100.5px = 200px (два поплавка 100.5px вписываются в контейнер 200px)
  • в IE8 +, Firefox 15.0.1, Chrome 22: 100.5px + 100.5px > 200px

Ответ 4

В последнее время нам пришлось сделать некоторые серьезные вычисления, отличные от пикселей, и мне нужно было проверить, будет ли браузер поддерживать подпиксельные макеты. Я создал тест для использования в Conditionizr или Modernizr используя некоторые другие ответы в качестве руководства:

conditionizr.add('subpixel-layout', function() {
    var $testWrap = $(
        '<div style="width: 4px; height: 2px; position: absolute; right: 0; bottom: 0;">' +
            '<div id="subpixel-layout-1" style="width: 2.5px; height: 1px; float: left;"></div>' +
            '<div id="subpixel-layout-2" style="width: 2.5px; height: 1px; float: left;"></div>' +
        '</div>'
    ).appendTo('body');

    var supported = $('#subpixel-layout-1').position().top !== $('#subpixel-layout-2').position().top;
    $testWrap.remove();
    return supported;
});

Затем вы можете использовать с:

conditionizr.on('!subpixel-layout', function () {
    // subpixel layout is NOT available
});

Вы должны иметь возможность сделать то же самое в Modernizr с помощью Modernizr.addTest(), но я не тестировал его.

Очевидно, что я использую jQuery здесь, но должен быть довольно простым и без него.