Настройка элементов списка с помощью иконок SVG

Я пытаюсь настроить пункты неупорядоченного списка в HTML с помощью иконок, которые я взял с некоторых веб-сайтов. Вот SVG-код для первой иконки, хранящийся в home.svg:

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
    stroke="blue" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
    class="feather feather-home">
    <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
    <polyline points="9 22 9 12 15 12 15 22"></polyline>
</svg>

И SVG-код для второй иконки хранится в linkedin.svg:

<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="blue"
  class="bi bi-linkedin" viewBox="0 0 16 16">
  <path
    d="M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854V1.146zm4.943 12.248V6.169H2.542v7.225h2.401m-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248-.822 0-1.359.54-1.359 1.248 0 .694.521 1.248 1.327 1.248h.016zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016a5.54 5.54 0 0 1 .016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225h2.4" />
</svg>

В html-документе я объявляю простой неупорядоченный список, элементы которого имеют разные классы:
И в моем файле styles.css я прикрепляю каждый из этих классов либо к home.svg, либо к linkedin.svg:

ul
{
    list-style-type: none;
}

li.first::before
{
    display: inline-block;
    width: 16px;
    content: url('home.svg');
}

li.second::before
{
    display: inline-block
    width: 16px;
    content: url('linkedin.svg');
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <ul>
        <li class="first">First item</li>
        <li class="second">Second item</li>
    </ul>
</body>
</html>

Кажется, это работает, и я получаю следующий результат:

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

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

ul {
  list-style-type: none;
}

li.first::before {
  display: inline-block;
  width: 16px;
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='blue' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-home'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E");    
}

li.second::before {
  display: inline-block;
  width: 16px;
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='blue' class='bi bi-linkedin' viewBox='0 0 16 16'%3E%3Cpath d='M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854V1.146zm4.943 12.248V6.169H2.542v7.225h2.401m-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248-.822 0-1.359.54-1.359 1.248 0 .694.521 1.248 1.327 1.248h.016zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016a5.54 5.54 0 0 1 .016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225h2.4' /%3E%3C/svg%3E");    
}
<ul>
  <li class="first">First item</li>
  <li class="second">Second item</li>
</ul>

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

Свободный перевод вопроса Customizing list items with SVG icons от участника @user32882.


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

Автор решения: Alexandr_TT

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

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

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

body {
  margin: 1em;
}

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

li {
  display: flex;
  align-items: center;
  gap: 0.5em;
  margin: 0.5em 0;
}

li::before {
  width: 20px;
  height: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
}

li:nth-child(1)::before {
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='blue' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-home'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E");    
}

li:nth-child(2)::before {
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='blue' class='bi bi-linkedin' viewBox='0 0 16 16'%3E%3Cpath d='M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854V1.146zm4.943 12.248V6.169H2.542v7.225h2.401m-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248-.822 0-1.359.54-1.359 1.248 0 .694.521 1.248 1.327 1.248h.016zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016a5.54 5.54 0 0 1 .016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225h2.4' /%3E%3C/svg%3E");    
}
<ul>
  <li>First item</li>
  <li>Second item</li>
</ul>

Свободный перевод ответа от участника @Brett Donald.

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

Размещение svgs через свойство содержимого будет учитывать внутренние размеры, если они определены шириной и высотой в dataURL.

Вот преувеличенный пример:

ul {
  list-style-type: none;
}

li.first::before {
  display: inline-block;
  width: 16px;
  content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 24 24' fill='none' stroke='blue' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-home'><path d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z' /><polyline points='9 22 9 12 15 12 15 22' /></svg>");    
}

li.second::before {
  display: inline-block;
  width: 16px;
  content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='blue' class='bi bi-linkedin' viewBox='0 0 16 16'><path d='M0 1.1c0-.6.5-1.1 1.2-1.1h13.6c.7 0 1.2.5 1.2 1.1v13.8c0 .6-.5 1.1-1.2 1.1h-13.6c-.7 0-1.2-.5-1.2-1.1zm4.9 12.3v-7.2h-2.4v7.2h2.4m-1.2-8.2c.9 0 1.4-.6 1.4-1.3s-.5-1.2-1.3-1.2-1.4.5-1.4 1.2.5 1.3 1.3 1.3zm5 8.2v-4c0-.3 0-.5 0-.6.2-.5.6-.9 1.3-.9s1.2.7 1.2 1.6v3.9h2.4v-4.1c0-2.3-1.2-3.3-2.8-3.3-1.3 0-1.8.7-2.1 1.2h-.1a5.5 5.5 0 01.1 0v-1h-2.4c0 .6 0 7.2 0 7.2h2.4' /></svg>");    
}
  
  <ul>
        <li class="first">First item</li>
        <li class="second">Second item</li>
    </ul>

Как вы можете видеть, первая иконка отображается размером 100x100 пикселей, хотя ширина псевдоэлемента определена как 16 пикселей.

Вы можете легко предотвратить это, удалив атрибуты ширины и высоты из встроенного в dataURL svg, например:

ul {
  list-style-type: none;
}

li:before{
  display: inline-block;
  width: 1em;
  margin-right:0.5em;
}


li.first::before {
  content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='blue' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-home'><path d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z' /><polyline points='9 22 9 12 15 12 15 22' /></svg>");
}

li.second::before {
  content: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='%230000ff' class='bi bi-linkedin' viewBox='0 0 16 16'><path d='M0 1.1c0-.6.5-1.1 1.2-1.1h13.6c.7 0 1.2.5 1.2 1.1v13.8c0 .6-.5 1.1-1.2 1.1h-13.6c-.7 0-1.2-.5-1.2-1.1zm4.9 12.3v-7.2h-2.4v7.2h2.4m-1.2-8.2c.9 0 1.4-.6 1.4-1.3s-.5-1.2-1.3-1.2-1.4.5-1.4 1.2.5 1.3 1.3 1.3zm5 8.2v-4c0-.3 0-.5 0-.6.2-.5.6-.9 1.3-.9s1.2.7 1.2 1.6v3.9h2.4v-4.1c0-2.3-1.2-3.3-2.8-3.3-1.3 0-1.8.7-2.1 1.2h-.1a5.5 5.5 0 01.1 0v-1h-2.4c0 .6 0 7.2 0 7.2h2.4' /></svg>");
}
<ul>
  <li class="first">First item</li>
  <li class="second">Second item</li>
</ul>

Однако убедитесь, что значения viewBox для всех значков правильные.

Благодарность Danny '365CSI' Engelman's в комментариях в других сообщениях, указывающих на то, что современные браузеры могут обрабатывать меньше экранированной/URLencoded svg-разметки в DataURL: замены двойных одинарных кавычек для значений атрибутов и %23 на # обычно достаточно. Это очень удобно для написания более читаемого CSS-кода.

Свободный перевод ответа от участника @herrstrietzel.

→ Ссылка