Почему CSS svg ‹rect /› имеет более толстую обводку справа и снизу?

Я создал несколько значков на основе svg для небольшого веб-сайта, над которым я работаю, но у меня возникли проблемы с тем, чтобы штрих выглядел так, как я хотел бы. Если вы посмотрите на это jsfiddle, вы увидите мою проблему. Обводка для внешнего <rect> составляет 1 пиксель по всему периметру, но по какой-то причине правая и нижняя стороны этого внешнего квадрата кажутся более толстыми, чем верхняя и левая стороны, что-то вроде эффекта тени.

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

Может ли кто-нибудь сказать мне, что здесь происходит и как это исправить?

Заранее спасибо.


person poncho    schedule 29.05.2020    source источник
comment
половина штриха находится за пределами SVG (добавьте overflow:visible для SVG, чтобы заметить это) .. вам нужно настроить окно просмотра   -  person Temani Afif    schedule 30.05.2020


Ответы (1)


То, с чем вы сталкиваетесь, действительно является случаем удивительного субпиксельного рендеринга. Видите ли, штрихи SVG применяются точно на пути, где они указаны. Пример: если путь проходит от точки (0,0) до (0,5) и ему назначается обводка шириной 1 пиксель, обводка покрывает прямоугольник (-0,5,0), (0,5,0), (0,5,5 ), (-0,5,5). Первое из этих изображений иллюстрирует это: иллюстрация штрихов из спецификации SVG

Ваш прямоугольник рисуется от (0,0) (положение по умолчанию) до (36,36). Поэтому обводка размещается таким образом, что находится ровно между пикселями экрана. Вот почему правый и нижний края выглядят размытыми.

Что случилось с верхним и левым краями? Что ж, поскольку вы не определили размер для своего SVG-изображения, браузер определил его за вас. По умолчанию нужно начинать с (0,0) (верхний левый угол) и сделать SVG 300 x 150 пикселей в ширину.

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

Как это исправить? Есть два варианта. Вариант 1 — разместить прямоугольник на половине пикселя:

<rect x="0.5" y="0.5" .../>

Другой вариант — переместить область просмотра вашего изображения по кругу, чтобы изображение в целом сместилось на полпикселя:

<svg viewBox="-0.5 -0.5 37 37">

Обратите внимание, что я установил ширину и высоту области просмотра на 37 пикселей. Это потому, что ваш прямоугольник будет иметь окончательный размер 37 пикселей: 36 пикселей для контура, а затем 0,5 пикселей с каждой стороны, где находится внешняя половина обводки в 1 пиксель.

Для общего обзора масштабирования SVG я предлагаю эту статью о CSS-трюках.

person Boldewyn    schedule 29.05.2020
comment
Спасибо за такой развернутый и хорошо написанный ответ! Я поиграюсь с исправлением viewBox и обязательно посмотрю эту статью CSS Tricks. - person poncho; 31.05.2020