Дополнительные пиксели, когда элемент встроен - PullRequest
1 голос
/ 08 июля 2020

Я изо всех сил пытаюсь понять, как работает расчет ширины / высоты во встроенных элементах. Мой вопрос очень похож на этот Дополнительные пиксели добавляются к элементу span , но немного отличаются.

Существует элемент div размером 50x50. Внутри div есть диапазон с отступом 15 пикселей. Диапазон содержит круг SVG размером 20x20.

Итак, есть три варианта использования:

  1. Только div - это блок

    • div - размер 50x50 ✔️
    • span - размер: 50x47 ❌ где эти три пикселя?
    • svg - size: 20x20 ✔️
  2. div и span - это блок

    • div - размер 50x50 ✔️
    • span - размер: 50x54 ❌ откуда берутся эти 4 пикселя?
    • svg - size: 20x20 ✔️
  3. все это блок

    • div - размер 50x50 ✔️
    • span - размер: 50x50 ✔️
    • svg - размер: 20x20 ✔️

span {
  /* display: block; */
  padding: 15px;
}

div {
  height: 50px;
  width: 50px;
}

svg {
  /* display: block; */
  height: 20px;
  width: 20px;
}
<div>
  <span>
          <svg
             viewBox="0 0 24 24"
             xmlns="http://www.w3.org/2000/svg"
          >
             <circle
               strokeLinecap="butt"
               strokeDasharray="64"
               cx="12"
               cy="12"
               r="9"
             />
        </svg>
      </span>
</div>

CodePen доступен здесь .

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

1 Ответ

2 голосов
/ 08 июля 2020

Здесь рассматривается ваш второй случай: Изображение внутри div имеет дополнительное пространство под изображением . Из-за выравнивания по умолчанию у вас будет дополнительное пространство под SVG. Это можно исправить, добавив display:block, как вы обнаружили, или vertical-align:top, что более логично в качестве решения:

span {
  display: block;
  padding: 15px;
  outline:1px solid green;
}

div {
  height: 50px;
  width: 50px;
  margin:30px;
  outline:1px solid blue;
}

svg {
  height: 20px;
  width: 20px;
  outline:1px solid red;
}
<div>
  <span>
      <svg
      viewBox="0 0 24 24"
      xmlns="http://www.w3.org/2000/svg"
    >
      <circle
        strokeLinecap="butt"
        strokeDasharray="64"
        cx="12"
        cy="12"
        r="9"
      />
    </svg>
  </span>
</div>

<div>
  <span>
      <svg
      viewBox="0 0 24 24"
      xmlns="http://www.w3.org/2000/svg" style="vertical-align:top;"
    >
      <circle
        strokeLinecap="butt"
        strokeDasharray="64"
        cx="12"
        cy="12"
        r="9"
      />
    </svg>
  </span>
</div>

Ваш первый случай немного сложен, потому что он не имеет ничего общего с SVG или шириной / высотой, которую вы устанавливаете. Все дело в метриках шрифтов.

Для упрощения давайте удалим div вокруг и рассмотрим разные SVG внутри одного диапазона и без отступов:

span {
  border: 1px solid green;
  margin:0 10px;
}

svg {
  outline: 1px solid red;
}
<span>
      <svg
      viewBox="0 0 24 24" height="20"
      xmlns="http://www.w3.org/2000/svg"
    >
      <circle
        strokeLinecap="butt"
        strokeDasharray="64"
        cx="12"
        cy="12"
        r="9"
      />
    </svg>
  </span>
  
  <span>
      <svg
      viewBox="0 0 24 24" height="30"
      xmlns="http://www.w3.org/2000/svg"
    >
      <circle
        strokeLinecap="butt"
        strokeDasharray="64"
        cx="12"
        cy="12"
        r="9"
      />
    </svg>
  </span>
  
  <span>
      <svg
      viewBox="0 0 24 24" height="50"
      xmlns="http://www.w3.org/2000/svg"
    >
      <circle
        strokeLinecap="butt"
        strokeDasharray="64"
        cx="12"
        cy="12"
        r="9"
      />
    </svg>
  </span>
  
   <span>
      <svg
      viewBox="0 0 24 24" height="200"
      xmlns="http://www.w3.org/2000/svg"
    >
      <circle
        strokeLinecap="butt"
        strokeDasharray="64"
        cx="12"
        cy="12"
        r="9"
      />
    </svg>
  </span>

Обратите внимание, что диапазон всегда имеет ту же высоту, что и SVG внутри, из-за природы встроенного элемента. Увеличим font-size

span {
  border: 1px solid green;
  margin:0 10px;
}

svg {
  outline: 1px solid red;
}

body {
  font-size:40px;
}
<span>
      <svg
      viewBox="0 0 24 24" height="20"
      xmlns="http://www.w3.org/2000/svg"
    >
      <circle
        strokeLinecap="butt"
        strokeDasharray="64"
        cx="12"
        cy="12"
        r="9"
      />
    </svg>
  </span>
  
  <span>
      <svg
      viewBox="0 0 24 24" height="30"
      xmlns="http://www.w3.org/2000/svg"
    >
      <circle
        strokeLinecap="butt"
        strokeDasharray="64"
        cx="12"
        cy="12"
        r="9"
      />
    </svg>
  </span>
  
  <span>
      <svg
      viewBox="0 0 24 24" height="50"
      xmlns="http://www.w3.org/2000/svg"
    >
      <circle
        strokeLinecap="butt"
        strokeDasharray="64"
        cx="12"
        cy="12"
        r="9"
      />
    </svg>
  </span>
  
   <span>
      <svg
      viewBox="0 0 24 24" height="200"
      xmlns="http://www.w3.org/2000/svg"
    >
      <circle
        strokeLinecap="butt"
        strokeDasharray="64"
        cx="12"
        cy="12"
        r="9"
      />
    </svg>
  </span>

Размах теперь больше по высоте, а SVG остался прежним. Вы также заметите небольшой зазор в нижней части SVG из-за выравнивания, которое я объяснил ранее. Попробуйте добавить font-size:0 и посмотрите результат.

Как видите, высота вашего диапазона не имеет ничего общего с SVG. К этой высоте вы добавляете вертикальный отступ, чтобы получить окончательную высоту. В вашем случае высота была 17px, и добавив отступ, у вас будет 47px, что близко к 50px, но не имеет отношения к.

Обратите внимание, что вы можете получить другой результат, чем 47px, если вы тестируете в разных браузерах / ОС, поскольку шрифт точно не будет одинаковым, а начальная высота может отличаться.

Если вы проверите спецификацию , вы можете прочитать:

Свойство «высота» не применяется. Высота области содержимого должна быть основана на шрифте ...

Вертикальное заполнение, граница и поле встроенного, незамещенного поля начинаются сверху и снизу область содержимого,

Создание элемента блока span изменит это поведение, и вы получите более интуитивный результат, как вы заметили в последнем примере: 2*15px отступов + 20px высоты SVG.

Связанный вопрос с более подробной информацией, чтобы понять, как рассчитывается высота элемента: Как определить высоту content-box блока и встроенного элемента

Другой связанный вопрос: Может ли c текстовый символ изменить высоту строки?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...