Как настраивать SVG с помощью Next.js и Tailwind CSS
Цель этой статьи - продемонстрировать, как настраивать SVG-изображения с помощью Next.js и Tailwind, не прибегая к внешним конфигурациям или использованию вспомогательных библиотек типа svgr/webpack.
В данном учебном пособии мы используем данное изображение.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve" width="512" height="512">
<g>
<path d="M405.333,0H106.667C47.786,0.071,0.071,47.786,0,106.667v298.667C0.071,464.214,47.786,511.93,106.667,512h298.667 C464.214,511.93,511.93,464.214,512,405.333V106.667C511.93,47.786,464.214,0.071,405.333,0z M426.667,172.352L229.248,369.771 c-16.659,16.666-43.674,16.671-60.34,0.012c-0.004-0.004-0.008-0.008-0.012-0.012l-83.563-83.541 c-8.348-8.348-8.348-21.882,0-30.229s21.882-8.348,30.229,0l83.541,83.541l197.44-197.419c8.348-8.318,21.858-8.294,30.176,0.053 C435.038,150.524,435.014,164.034,426.667,172.352z" />
</g>
</svg>
Стандартное поведение Next.js с тегом <Image>
не позволяет изменять свойство fill
SVG. Это становится проблемой, когда нам нужно изменить цвет SVG-изображения при наведении мыши, например, используя такие CSS-классы Tailwind, как fill-white
или bg-white
. Такой подход не работает, поскольку мы не изменяем непосредственно свойство fill
в <svg>
, а на момент написания этой статьи (Next 13.5.4)
тег <Image/>
не поддерживает изменение fill
в SVG.
import Image from 'next/image';
import checkbox from '../../public/icons/checkbox.svg';
const Home = () => {
return (
<main className='h-screen bg-zinc-800 flex items-center justify-center'>
<Image
src={checkbox}
alt='checkbox'
className='w-20 h-20 fill-white'
/>
</main>
);
}
export default Home;
Для решения этой проблемы необходимо создать компонент для SVG, удалив из тега SVG такие стилевые свойства, как width
, height
и преимущественно fill
. Эти свойства будут передаваться SVG через свойство className
компонента. Вот как это сделать:
import { twMerge } from 'tailwind-merge';
interface CheckboxProps {
className?: string;
}
const Checkbox = ({ className }: CheckboxProps) => {
return (
<svg
xmlns='http://www.w3.org/2000/svg'
version='1.1'
id='Capa_1'
x='0px'
y='0px'
viewBox='0 0 512 512'
width='512'
height='512'
className={twMerge('w-20 h-20', className)}
>
<g>
<path d='M405.333,0H106.667C47.786,0.071,0.071,47.786,0,106.667v298.667C0.071,464.214,47.786,511.93,106.667,512h298.667 C464.214,511.93,511.93,464.214,512,405.333V106.667C511.93,47.786,464.214,0.071,405.333,0z M426.667,172.352L229.248,369.771 c-16.659,16.666-43.674,16.671-60.34,0.012c-0.004-0.004-0.008-0.008-0.012-0.012l-83.563-83.541 c-8.348-8.348-8.348-21.882,0-30.229s21.882-8.348,30.229,0l83.541,83.541l197.44-197.419c8.348-8.318,21.858-8.294,30.176,0.053 C435.038,150.524,435.014,164.034,426.667,172.352z' />
</g>
</svg>
);
};
export default Checkbox;
Наконец, наш файл page.tsx
будет выглядеть следующим образом:
import Image from 'next/image';
import Checkbox from '@/components/svg/Checkbox';
import checkbox from '../../public/icons/checkbox.svg';
const Home = () => {
return (
<main className='h-screen bg-zinc-800 flex items-center justify-center gap-6'>
<Image
src={checkbox}
alt='checkbox'
className='w-20 h-20 fill-white'
/>
<Checkbox className='fill-white hover:fill-red-600' />
</main>
);
};
export default Home;
Теперь мы можем настраивать SVG в соответствии с внешними состояниями приложения и действиями пользователя, такими как наведение курсора. Это простое решение, но не очень интуитивное, поскольку тег <Image/>
в Next.js не очень эффективно работает с подобными сценариями.