Не работает vetical-align: middle

Выравниваю текст относительно картинки по центру, но всё равно текст не выравнивается идеально по центру. Почему?

Код прикладываю

#picture {
  border-radius: 100px;
  object-fit: cover;
  width: 40px;
  height: 40px;
  vertical-align: middle;
  box-shadow: 0 0 4px black;
  border: 2px solid white;
}
<ul style="text-align: center;">
  <li style="min-width: 135px; display: table;">
    <div style="display: table-cell;">
      <a href="" style="vertical-align: middle; padding: 10px; background: rgba(0,0,0,0.3);">
        <img src="https://avatars.mds.yandex.net/get-zen_doc/1136050/pub_5d62d5b66d29c100ad1dc939_5d62dee5ddfef600ae0905f2/scale_1200" id="picture" style="margin-right:5px;" />Котик
      </a>
    </div>
  </li>
</ul>


Ответы (3 шт):

Автор решения: adudnik.ru

Все у вас верно выровненно. Проблема в другом. Шрифты создают для себя условный "контейнер" в котором происходит отрисовка букв. Добавляется пространство как сверху, так и снизу. Это нужно для всяких точек над Ё, хвостиков Й и т.д.

введите сюда описание изображения

У текущего вашего шрифта вверху есть дополнительные несколько пикселей в сравнении с низом + одна буква заглавная, остальные строчные + в нижней части у вас underline. В итоге создается иллюзия отсутствия выравнивания, т.к. область над шрифтом получается выше.

Вот что будете если сменить шрифт на helvetica, убрать underline и сделать все буквы заглавными.

Пример:

#picture {
  border-radius: 100px;
  object-fit: cover;
  width: 40px;
  height: 40px;
  vertical-align: middle;
  box-shadow: 0 0 4px black;
  border: 2px solid white;
}

.link {
  vertical-align: middle;
  padding: 10px;
  background: rgba(0, 0, 0, 0.3);
  font-family:helvetica;
  text-transform:uppercase;
  text-decoration:none;
}
<ul style="text-align: center;">
  <li style="min-width: 135px; display: table;">
    <div style="display: table-cell;">
      <a href="" class="link">
        <img src="https://avatars.mds.yandex.net/get-zen_doc/1136050/pub_5d62d5b66d29c100ad1dc939_5d62dee5ddfef600ae0905f2/scale_1200" id="picture" style="margin-right:5px;" />Котик
      </a>
    </div>
  </li>
</ul>

Запустите пример.

Как видите результат гораздо лучше и ближе к "идеальному" выравниванию.

Но как быть в вашем случае если вы не хотите менять шрифт, делать буквы заглавными, убирать подчеркивание и т.д.?

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

Вот так:

#picture {
  border-radius: 100px;
  object-fit: cover;
  width: 40px;
  height: 40px;
  vertical-align: middle;
  box-shadow: 0 0 4px black;
  border: 2px solid white;
}

.link {
  vertical-align: middle;
  padding: 10px;
  padding-top:7px;
  background: rgba(0, 0, 0, 0.3); 
}
<ul style="text-align: center;">
  <li style="min-width: 135px; display: table;">
    <div style="display: table-cell;">
      <a href="" class="link">
        <img src="https://avatars.mds.yandex.net/get-zen_doc/1136050/pub_5d62d5b66d29c100ad1dc939_5d62dee5ddfef600ae0905f2/scale_1200" id="picture" style="margin-right:5px;" />Котик
      </a>
    </div>
  </li>
</ul>

Не могу говорить об эффективности в плане кроссплатформенности и кроссбраузерности такого решения, т.к. выглядит оно явно костыльным. Рекомендую поработать с шрифтом до нужного вам эффекта.

Подробнее об отрисовке шрифтов, позиционировании, line-height и прочем в контексте вашего вопроса:

https://css-live.ru/css/metriki-shrifta-line-height-vertical-align.html

→ Ссылка
Автор решения: Дмитрий

Проблема решилась добавлением <span> к тексту, который нужно выравнивать и добавить ему свойство vertical-align: middle;

→ Ссылка
Автор решения: Vladimir Rodichev

Можешь использовать вертикальное выравнивание с помощью Флекса:

display: flex;
align-items: center;

Только код в твоем случае предстоит отредактировать.

→ Ссылка