Hello im desperately trying to size an svg in react.
No matter what i do the size stays the same even though the div containing it is much smaller.
In normal html and css it would size automatically what am i doing wrong?
import React, { Component } from 'react';
import logo from './logo.svg'
class Logo extends Component {
render(){
return(
<div className="size">
<img src={logo} alt={"logo"}/>
</div>
);
}
}
export default Logo
svg part
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="none">
<g transform="translate(0,0)">
<title>Logo</title>
<path fill="#009FE3" d="M36.9 707.8H1747V1000H36.9"/>
<path d="M385 104.1h1.7l138.7 503.5h86.3L771.6.1h-90.5L567.7 494.2H566L429.8.1h-89.7L203.9 494.2h-1.7L88.8.1H0l158.3 607.5h86.2m889.6-119.4c-16.2 22.1-35.4 38.8-57.7 50.3-22.3 11.5-47 17.3-74.2 17.3-12 .2-26.4-2.9-43.3-9.2-16.9-6.3-31.9-16.8-45-31.5-13.1-14.7-20-34.7-20.8-59.9.3-31.5 9.5-56.9 27.6-76.1 18.1-19.2 43.6-38.7 76.4-58.3l137 167.4zm-110.9-252.1c-12.5-11.9-25.4-27.4-38.6-46.5-13.2-19.1-20.4-38.8-21.5-59.2-.3-7.2 1.2-15.9 4.5-26.1 3.3-10.2 10.1-19.3 20.3-27.3 10.2-8 25.6-12.1 46.2-12.6 13.5-.6 27.4 3.8 41.8 13.1 14.4 9.3 22.2 27.2 23.4 53.7-1.2 25.6-9.8 46.7-26 63.5-16.1 16.9-32.8 30.7-50.1 41.4zm195.5 240.3c15.5-29 27.2-56.8 35-83.4 7.8-26.6 12.5-50.4 14.1-71.4h-70.2c-3.5 21.2-6.9 38-10 50.2-3.2 12.2-8 27.1-14.5 44.5l-110.8-132c15.5-10 31.5-21.9 48.2-35.8 16.7-13.9 30.9-30.8 42.6-50.8 11.7-20 17.8-44.1 18.3-72.4.3-31.8-10.4-60.3-32.2-85.4-21.8-25.1-56.4-38.3-103.9-39.8-46.7 1.3-82.3 15-106.8 41.3-24.5 26.3-36.8 57.6-37 94-.1 25.2 5.2 47.4 15.7 66.6 10.5 19.2 26.7 41.9 48.6 67.9-54.9 30.5-91.8 60-110.7 88.3-18.9 28.3-27.6 62.6-26.3 102.9-.6 16.6 3.6 37.2 12.6 61.9 9 24.7 26.4 46.7 52.3 66.2 25.8 19.5 63.7 29.8 113.5 30.9 43.6-.5 79-8.2 106.1-23.3 27.1-15 50.7-34.6 70.6-58.8l56.7 69.3h96.4l-108.3-130.9zm70.1-403.7h205.6v534.8h82V72.7H1782V0h-493.2"/>
<path fill="#FFF" d="M343.3 821.9h-24.1L305.3 886h-.3l-13.4-64.1h-23.7L255.4 886h-.4l-13.9-64.1h-24.9l25.1 89.2h24.1l13.9-65h.4l13.9 65h24.1m192.6-89.2h-24.1L472.3 886h-.3l-13.4-64.1H435L422.4 886h-.3l-13.9-64.1h-25.1l25.2 89.2h24.2l13.9-65h.3l13.9 65h24.1m192.7-89.2h-24.1L639.4 886h-.4l-13.5-64.1h-23.6L589.3 886h-.3l-13.9-64.1h-25l25.2 89.2h24.1l13.9-65h.3l13.9 65h24.2m69.3-24.5h25.1V911H721zm109.4 24.5h23.4c3.2-15.3 5.8-27.8 7.8-37.6 2-9.7 3.7-17.7 4.9-23.9 1.3-6.2 2.3-11.8 3.2-16.6.9-4.9 1.7-10.1 2.6-15.7h.3c1 5.6 1.9 11 2.9 16.1.9 5.1 2 10.9 3.3 17.3 1.3 6.5 2.9 14.5 4.9 24.1 2 9.6 4.5 21.7 7.6 36.3h24.1l33.8-120.2h-25.5c-3.9 16.4-7 29.7-9.4 40-2.4 10.3-4.2 18.5-5.5 24.5-1.3 6-2.3 10.7-3 14.2-.7 3.5-1.3 6.5-1.7 9.2h-.3c-.6-3.7-1.3-7.4-2-11-.7-3.6-1.6-8.3-2.7-14-1.2-5.7-2.8-13.5-4.9-23.5-2.1-10-4.9-23.1-8.4-39.4h-26.6c-3.2 15.6-5.7 28.5-7.7 38.6-2 10.1-3.5 18.2-4.7 24.3-1.1 6.1-2 11.1-2.7 14.8-.7 3.8-1.2 7.2-1.7 10.2h-.3c-.5-3.3-1.1-6.7-1.7-10.3-.7-3.6-1.6-8.3-2.9-14.1-1.2-5.9-3-13.8-5.3-23.9-2.3-10.1-5.4-23.3-9.2-39.6h-26.8l34.2 120.2zm246.9-89.2h-23.4v51.4c-.3 7.8-2.3 13.2-6.2 16.1-3.8 2.9-7.8 4.3-11.9 4.2-3.8.2-7.2-.9-10.3-3.1-3.1-2.2-4.7-6.7-4.9-13.4v-55.3h-23.4v58.6c.2 11.3 3 19.6 8.6 24.9 5.5 5.3 12.8 7.9 21.7 7.9 6.2 0 11.6-1.3 16.2-3.9s8.2-6.2 10.9-11h.3v12.5h22.4v-88.9zm111.6-9.9h36.3v-21.3h-97.8V812h36.3v99.1h25.2m69.7-24.5h25.1V911h-25.1zm165.1-95.9h-23.4v42.7h-.3c-1.7-3.1-4.6-6.1-8.6-9.1s-9.7-4.6-17.2-4.8c-6.6 0-12.7 1.7-18.3 5-5.6 3.4-10.1 8.4-13.5 15.2-3.4 6.8-5.1 15.3-5.2 25.6 0 8.3 1.3 16.1 3.8 23.3 2.6 7.2 6.6 13.1 12.2 17.6 5.5 4.5 12.7 6.8 21.5 7 5 .1 9.8-.9 14.4-3s8.4-5.6 11.4-10.5h.3V911h22.9V790.7zm-62.5 76.5c-.1-7.3 1.4-13.6 4.4-18.9 3-5.3 8.2-8.1 15.6-8.4 5.3.1 9.4 1.5 12.4 4.3 2.9 2.8 5 6.3 6.1 10.6 1.1 4.3 1.7 8.9 1.7 13.8.1 6.9-1.5 12.8-4.8 17.8s-8.6 7.6-16 7.9c-5-.2-8.9-1.7-11.7-4.6-2.8-3-4.8-6.5-5.9-10.6-1.3-4.4-1.9-8.2-1.8-11.9zm172.4 17.7c-1 3.2-3 5.6-5.8 7.3-2.8 1.6-5.9 2.5-9.3 2.5-6.2-.1-10.8-1.5-13.7-4.2-2.9-2.6-4.8-5.6-5.7-9-.9-3.4-1.4-6.3-1.5-8.6h61.1v-4.2c-.2-13.4-2.5-23.7-6.9-30.8-4.4-7.1-9.8-12-16.2-14.6s-12.6-3.8-18.7-3.7c-9.7.2-17.4 2-23.1 5.5-5.8 3.5-10 7.9-12.8 13-2.8 5.1-4.7 10.1-5.5 15-.9 4.9-1.3 8.7-1.2 11.6.3 18.1 4.5 30.8 12.8 38.1 8.2 7.3 18.8 10.9 31.6 10.6 5.2.1 10.4-.8 15.6-2.6 5.2-1.8 9.9-4.8 14.1-8.9 4.2-4.2 7.4-9.8 9.5-16.9l-24.3-.1zm-35.3-27.2c.7-5.9 2.5-10.5 5.5-13.8 3-3.3 7.2-5 12.8-5 4-.1 7.8 1.2 11.4 4 3.6 2.8 5.9 7.7 6.7 14.8h-36.4z"/>
</g>
</svg>
css part
body
{
margin: 0;
height: 100%;
overflow: hidden
}
.wrapper
{
min-width: 320px;
max-width: 4096px;
width: 100%;
height: calc(100vh - 0.4vw);
float:left;
}
.size
{
width:100px;
}
asked Aug 27, 2018 at 10:08
1
Try this, it will be working perfectly.
import Logo from "./logo.svg";
<img
src={Logo}
style={{ height: 53, width: 36 }}
alt="website logo"
/>
answered Oct 14, 2019 at 18:59
1
If you import a SVG file as a component:
import { ReactElement as ComponentName } from "./file.svg"
You can change the size using CSS transform: scale(2)
in <ComponentName />
, which in React can be achieved using className
or a global CSS file.
Note: To change the color you can use .componentClass path { fill: "color" }
, but if you change the scale on .componentClass path
it’ll not look cool, even if you change the width
and height
on the component .componentClass
, which will actually change the SVG container size and not the content…
answered Jun 3, 2020 at 22:41
4
Hi I’m not sure how is your webpack configured to resolve modules. But here is solution for your case :
import React, { Component } from 'react';
import logo from './logo.svg'
const SvgIcon = () => (<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="none">
<g transform="translate(0,0)">
<title>Logo</title>
<path fill="#009FE3" d="M36.9 707.8H1747V1000H36.9" />
<path d="M385 104.1h1.7l138.7 503.5h86.3L771.6.1h-90.5L567.7 494.2H566L429.8.1h-89.7L203.9 494.2h-1.7L88.8.1H0l158.3 607.5h86.2m889.6-119.4c-16.2 22.1-35.4 38.8-57.7 50.3-22.3 11.5-47 17.3-74.2 17.3-12 .2-26.4-2.9-43.3-9.2-16.9-6.3-31.9-16.8-45-31.5-13.1-14.7-20-34.7-20.8-59.9.3-31.5 9.5-56.9 27.6-76.1 18.1-19.2 43.6-38.7 76.4-58.3l137 167.4zm-110.9-252.1c-12.5-11.9-25.4-27.4-38.6-46.5-13.2-19.1-20.4-38.8-21.5-59.2-.3-7.2 1.2-15.9 4.5-26.1 3.3-10.2 10.1-19.3 20.3-27.3 10.2-8 25.6-12.1 46.2-12.6 13.5-.6 27.4 3.8 41.8 13.1 14.4 9.3 22.2 27.2 23.4 53.7-1.2 25.6-9.8 46.7-26 63.5-16.1 16.9-32.8 30.7-50.1 41.4zm195.5 240.3c15.5-29 27.2-56.8 35-83.4 7.8-26.6 12.5-50.4 14.1-71.4h-70.2c-3.5 21.2-6.9 38-10 50.2-3.2 12.2-8 27.1-14.5 44.5l-110.8-132c15.5-10 31.5-21.9 48.2-35.8 16.7-13.9 30.9-30.8 42.6-50.8 11.7-20 17.8-44.1 18.3-72.4.3-31.8-10.4-60.3-32.2-85.4-21.8-25.1-56.4-38.3-103.9-39.8-46.7 1.3-82.3 15-106.8 41.3-24.5 26.3-36.8 57.6-37 94-.1 25.2 5.2 47.4 15.7 66.6 10.5 19.2 26.7 41.9 48.6 67.9-54.9 30.5-91.8 60-110.7 88.3-18.9 28.3-27.6 62.6-26.3 102.9-.6 16.6 3.6 37.2 12.6 61.9 9 24.7 26.4 46.7 52.3 66.2 25.8 19.5 63.7 29.8 113.5 30.9 43.6-.5 79-8.2 106.1-23.3 27.1-15 50.7-34.6 70.6-58.8l56.7 69.3h96.4l-108.3-130.9zm70.1-403.7h205.6v534.8h82V72.7H1782V0h-493.2" />
<path fill="#FFF" d="M343.3 821.9h-24.1L305.3 886h-.3l-13.4-64.1h-23.7L255.4 886h-.4l-13.9-64.1h-24.9l25.1 89.2h24.1l13.9-65h.4l13.9 65h24.1m192.6-89.2h-24.1L472.3 886h-.3l-13.4-64.1H435L422.4 886h-.3l-13.9-64.1h-25.1l25.2 89.2h24.2l13.9-65h.3l13.9 65h24.1m192.7-89.2h-24.1L639.4 886h-.4l-13.5-64.1h-23.6L589.3 886h-.3l-13.9-64.1h-25l25.2 89.2h24.1l13.9-65h.3l13.9 65h24.2m69.3-24.5h25.1V911H721zm109.4 24.5h23.4c3.2-15.3 5.8-27.8 7.8-37.6 2-9.7 3.7-17.7 4.9-23.9 1.3-6.2 2.3-11.8 3.2-16.6.9-4.9 1.7-10.1 2.6-15.7h.3c1 5.6 1.9 11 2.9 16.1.9 5.1 2 10.9 3.3 17.3 1.3 6.5 2.9 14.5 4.9 24.1 2 9.6 4.5 21.7 7.6 36.3h24.1l33.8-120.2h-25.5c-3.9 16.4-7 29.7-9.4 40-2.4 10.3-4.2 18.5-5.5 24.5-1.3 6-2.3 10.7-3 14.2-.7 3.5-1.3 6.5-1.7 9.2h-.3c-.6-3.7-1.3-7.4-2-11-.7-3.6-1.6-8.3-2.7-14-1.2-5.7-2.8-13.5-4.9-23.5-2.1-10-4.9-23.1-8.4-39.4h-26.6c-3.2 15.6-5.7 28.5-7.7 38.6-2 10.1-3.5 18.2-4.7 24.3-1.1 6.1-2 11.1-2.7 14.8-.7 3.8-1.2 7.2-1.7 10.2h-.3c-.5-3.3-1.1-6.7-1.7-10.3-.7-3.6-1.6-8.3-2.9-14.1-1.2-5.9-3-13.8-5.3-23.9-2.3-10.1-5.4-23.3-9.2-39.6h-26.8l34.2 120.2zm246.9-89.2h-23.4v51.4c-.3 7.8-2.3 13.2-6.2 16.1-3.8 2.9-7.8 4.3-11.9 4.2-3.8.2-7.2-.9-10.3-3.1-3.1-2.2-4.7-6.7-4.9-13.4v-55.3h-23.4v58.6c.2 11.3 3 19.6 8.6 24.9 5.5 5.3 12.8 7.9 21.7 7.9 6.2 0 11.6-1.3 16.2-3.9s8.2-6.2 10.9-11h.3v12.5h22.4v-88.9zm111.6-9.9h36.3v-21.3h-97.8V812h36.3v99.1h25.2m69.7-24.5h25.1V911h-25.1zm165.1-95.9h-23.4v42.7h-.3c-1.7-3.1-4.6-6.1-8.6-9.1s-9.7-4.6-17.2-4.8c-6.6 0-12.7 1.7-18.3 5-5.6 3.4-10.1 8.4-13.5 15.2-3.4 6.8-5.1 15.3-5.2 25.6 0 8.3 1.3 16.1 3.8 23.3 2.6 7.2 6.6 13.1 12.2 17.6 5.5 4.5 12.7 6.8 21.5 7 5 .1 9.8-.9 14.4-3s8.4-5.6 11.4-10.5h.3V911h22.9V790.7zm-62.5 76.5c-.1-7.3 1.4-13.6 4.4-18.9 3-5.3 8.2-8.1 15.6-8.4 5.3.1 9.4 1.5 12.4 4.3 2.9 2.8 5 6.3 6.1 10.6 1.1 4.3 1.7 8.9 1.7 13.8.1 6.9-1.5 12.8-4.8 17.8s-8.6 7.6-16 7.9c-5-.2-8.9-1.7-11.7-4.6-2.8-3-4.8-6.5-5.9-10.6-1.3-4.4-1.9-8.2-1.8-11.9zm172.4 17.7c-1 3.2-3 5.6-5.8 7.3-2.8 1.6-5.9 2.5-9.3 2.5-6.2-.1-10.8-1.5-13.7-4.2-2.9-2.6-4.8-5.6-5.7-9-.9-3.4-1.4-6.3-1.5-8.6h61.1v-4.2c-.2-13.4-2.5-23.7-6.9-30.8-4.4-7.1-9.8-12-16.2-14.6s-12.6-3.8-18.7-3.7c-9.7.2-17.4 2-23.1 5.5-5.8 3.5-10 7.9-12.8 13-2.8 5.1-4.7 10.1-5.5 15-.9 4.9-1.3 8.7-1.2 11.6.3 18.1 4.5 30.8 12.8 38.1 8.2 7.3 18.8 10.9 31.6 10.6 5.2.1 10.4-.8 15.6-2.6 5.2-1.8 9.9-4.8 14.1-8.9 4.2-4.2 7.4-9.8 9.5-16.9l-24.3-.1zm-35.3-27.2c.7-5.9 2.5-10.5 5.5-13.8 3-3.3 7.2-5 12.8-5 4-.1 7.8 1.2 11.4 4 3.6 2.8 5.9 7.7 6.7 14.8h-36.4z" />
</g>
</svg>)
class Logo extends Component {
render() {
return (
<div style={{height:'200px',
width: '500px'}} className="size">
<SvgIcon />
</div>
);
}
}
export default Logo
answered Aug 27, 2018 at 11:52
Sakhi MansoorSakhi Mansoor
7,6025 gold badges21 silver badges36 bronze badges
4
Open SVG file in a text editor and remove width
and height
attributes from the root node
answered Feb 4, 2021 at 18:23
PawelPawel
14.8k4 gold badges66 silver badges70 bronze badges
3
This can easily be done by editing the respective SVG code directly. See as below:
<svg id="_x31_" enable-background="new 0 0 24 24" height="250" viewBox="0 0 24 24" width="250" xmlns="http://www.w3.org/2000/svg"><path d="m20.5 18h-6c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h6c.276 0 .5.224.5.5s-.224.5-.5.5z"/><path d="m13.5 9h-10c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h10c.276 0 .5.224.5.5s-.224.5-.5.5z"/><path d="m10.5 12h-7c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h7c.276 0 .5.224.5.5s-.224.5-.5.5z"/><path d="m8.5 15h-5c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h5c.276 0 .5.224.5.5s-.224.5-.5.5z"/></svg>
You only need to change the height and width attributes respectively.
answered Mar 4, 2021 at 13:58
TeeTee
3853 silver badges13 bronze badges
I had the same issue and fix it by first,
-
importing the svg as a ReactComponent
-
wrapping the component in a div
-
making the component width 100% of it’s parent
-
ajusting the height to get the desire size
For me, that worked and it kept its proportions
answered Oct 21, 2022 at 15:51
I have resized the icon using the user7075574’s import
(reference to that How to display svg icons(.svg files) in UI using React Component?)
import { ReactElement as IconTestName } from "./testname.svg"
and used props on JSX.Element like
const AppWithSingleIcon = () => <IconTestName height={24} width={24} fill='orange' />
This gives just enough control to resize SVG path without an external containing div. If the path size is set e.g. at size (24, 24) then setting the prop height={36} will not resize because the prop width={24} is a limiting factor.
answered Dec 22, 2021 at 9:54
Erkka MutanenErkka Mutanen
5291 gold badge8 silver badges13 bronze badges
1
You must make:
import logo from './logo.svg'
const Logo = () => {
return (
<logo height='200px' width='500px' alt="tuvieja"/>
);
}
}
answered Dec 19, 2018 at 21:14
1
In this article, we will see how to zoom SVG images in React JS. It is really useful in some cases. We will use the react-svg-pan-zoom package to create a feature that will zoom-in or rotate our SVG image.
First create a React project −
npx create-react-app tutorialpurpose
Go to the project directory −
cd tutorialpurpose
Example
Install the react-svg-pan-zoom package −
npm i --save react-svg-pan-zoom
This package will allow us to implement an area over which we can
zoom-in and zoom-out and even rotate an image.
Add the following lines of code in App.js −
import React, { useRef, useEffect } from "react"; import { UncontrolledReactSVGPanZoom } from "react-svg-panzoom"; export default function App() { const Viewer = useRef(null); useEffect(() => { Viewer.current.fitToViewer(); }, []); const _zoomOnViewerCenter = () => Viewer.current.zoomOnViewerCenter(1.1); const _fitSelection = () => Viewer.current.fitSelection(40,40, 200, 200); const _fitToViewer = () => Viewer.current.fitToViewer(); return ( <div> <h1>UncontrolledReactSVGPanZoom</h1> <hr /> <button className="btn" onClick={() =>_zoomOnViewerCenter()}>Zoom on center </button> <button className="btn" onClick={() =>_fitSelection()}> Zoom area 200x200 </button> <button className="btn" onClick={() => _fitToViewer()}> Fit </button> <hr /> <UncontrolledReactSVGPanZoom ref={Viewer} width={500} height={500}> <svg width={617} height={316}> <g fillOpacity=".5" strokeWidth="4"> <rectx="400" y="40" width="100" height="200" fill="#4286f4" stroke="#f4f142" /> </g> </svg> </UncontrolledReactSVGPanZoom> </div> ); }
Explanation
This is the default code from the documentation.
-
We first created a reference, where we referenced its default view, which will fit to the screen.
-
Then we created 3 functions to change the zoom settings.
-
In <UncontrolledReactSVGPanZoom> we give reference and inside it, we add an SVG image to operate.
Output
On execution, it will produce the following output −
Your browser does not support HTML5 video.
In this article, we will see how to zoom SVG images in React JS. It is really useful in some cases. We will use the react-svg-pan-zoom package to create a feature that will zoom-in or rotate our SVG image.
First create a React project −
npx create-react-app tutorialpurpose
Go to the project directory −
cd tutorialpurpose
Example
Install the react-svg-pan-zoom package −
npm i --save react-svg-pan-zoom
This package will allow us to implement an area over which we can
zoom-in and zoom-out and even rotate an image.
Add the following lines of code in App.js −
import React, { useRef, useEffect } from "react"; import { UncontrolledReactSVGPanZoom } from "react-svg-panzoom"; export default function App() { const Viewer = useRef(null); useEffect(() => { Viewer.current.fitToViewer(); }, []); const _zoomOnViewerCenter = () => Viewer.current.zoomOnViewerCenter(1.1); const _fitSelection = () => Viewer.current.fitSelection(40,40, 200, 200); const _fitToViewer = () => Viewer.current.fitToViewer(); return ( <div> <h1>UncontrolledReactSVGPanZoom</h1> <hr /> <button className="btn" onClick={() =>_zoomOnViewerCenter()}>Zoom on center </button> <button className="btn" onClick={() =>_fitSelection()}> Zoom area 200x200 </button> <button className="btn" onClick={() => _fitToViewer()}> Fit </button> <hr /> <UncontrolledReactSVGPanZoom ref={Viewer} width={500} height={500}> <svg width={617} height={316}> <g fillOpacity=".5" strokeWidth="4"> <rectx="400" y="40" width="100" height="200" fill="#4286f4" stroke="#f4f142" /> </g> </svg> </UncontrolledReactSVGPanZoom> </div> ); }
Explanation
This is the default code from the documentation.
-
We first created a reference, where we referenced its default view, which will fit to the screen.
-
Then we created 3 functions to change the zoom settings.
-
In <UncontrolledReactSVGPanZoom> we give reference and inside it, we add an SVG image to operate.
Output
On execution, it will produce the following output −
Your browser does not support HTML5 video.
If you are putting out digital content into the world wide web to publicize your work, then there is a high chance that your audience will view it on a mobile device. For text and images, this is not a huge problem with modern CSS. But if the content is a data visualization using SVG elements, this might be a problem.
I initially ran into problems on mobile devices with some graphs I was working on creating. After a lot of fumbling, I made some reusable components that can shield me from this pain.
How much space does the SVG have to grow?
There are a few abstractions to consider when working out how much space is available to scale an SVG document.
Browser viewport
The browser viewport is the visible area of a web page.
SVG viewport
The SVG viewport is analogous to the browser’s viewport only it is the visible area of an SVG document. An SVG document can be as high and wide as you want, but only part of the document can be visible at one time.
We want to avoid hardcoded width and height attributes like in the example below because they cannot adapt to the multitude of devices that might be viewing this document:
export const App: React.FC = () => ( <svg width="1000" height="1000"> <rect x="20%" y="20%" width="1000" height="1000" rx="20" style={{ fill: '#ff0000', stroke: '#000000', strokeWidth: '2px' }} /> <rect x="30%" y="30%" width="1000" height="1000" rx="40" style={{ fill: '#0000ff', stroke: '#000000', strokeWidth: '2px', fillOpacity: 0.7 }} /> </svg> );
The above component renders this document:
The above SVG document of 2 <rect/> elements is larger than the SVG viewport, and because of this, only part of it is visible.
A magical attribute called the viewBox is the answer to a lot of our SVG responsive needs.
viewBox and coordinate systems
The definition from mdn for the viewBox
attribute is:
The viewBox attribute defines the position and dimension, in user space, of an SVG viewport.
I don’t know about you, but I had more questions than answers when I first read that. What on earth is user space?
If you have sat maths to any level, then you will have come across euclidean space with the classic x
and y
axes:
SVG coordinate space is different because the point (0, 0) is at the top left-hand corner and not the center.
If we add a viewBox
attribute to the SVG that was created earlier, then we can regain control of the sizing of the SVG viewport:
export const App: React.FC = () => ( <svg preserveAspectRatio="xMaxYMid meet" viewBox="0 0 529 470"> <rect x="20%" y="20%" width="1000" height="1000" rx="20" style={{ fill: '#ff0000', stroke: '#000000', strokeWidth: '2px' }} /> <rect x="30%" y="30%" width="1000" height="1000" rx="40" style={{ fill: '#0000ff', stroke: '#000000', strokeWidth: '2px', fillOpacity: 0.7 }} /> </svg> );
The two <rect/> elements are now smaller than the SVG viewport thanks to this magical attribute.
viewBox math
Below is an example of a viewBox
attribute:
viewBox="-200 -100 3000 400"
The magical four numbers in the attribute can shrink or expand the elements and transform their position. But how?
The viewBox does a lot with very little, such as:
- It defines the aspect ratio of the image
- It defines how all the lengths and coordinates used inside the SVG should be scaled to fit the space available
- It defines the origin of the new coordinate system
I like to remember the initial four values like this:
viewBox="minX minY width height"
A new set of coordinates are copied from the existing SVG viewport coordinates with the addition of the viewBox. This new set of coordinates is known as a user space
. The mdn cryptic explanation mentioned this:
The viewBox attribute defines the position and dimension, in user space, of an SVG viewport.
The first two values of the viewBox are -200 and -100, and these values will shift the image right and down from the top-left origin:
<svg width="500px" height="100px" viewBox="-200 -100 3000 400" >
The last two values, 3000 and 400, allow us to zoom into or away from our SVG image.
The SVG element has a width of 500px and a height of 100px. With the addition of the viewBox attribute, a new user coordinate system of 3000 units and 400 hundred units vertically is at our disposal.
The new user space maps to the viewport coordinate system, and 1 unit of the new space is equal to this calculation:
height = SVG viewport height ÷ viewBox height vertically width = SVG viewport width ÷ viewBox width horizontally
The viewBox on its own will not cure all our responsive needs. We cannot use hardcoded values in the real world. We need to get new values when the component is mounted, or it resizes.
Responsive SVG
Below is my ResponsiveSVG
component from my very own @cutting/svg package:
export function ResponsiveSVG<E extends HTMLElement = HTMLElement>({ elementRef, children, preserveAspectRatio = 'xMinYMin slice', innerRef, className, options = {}, }: PropsWithChildren<ParentsizeSVGProps<E>>): JSX.Element | null { const { width, height } = useParentSize(elementRef, options); const aspect = width / height; const adjustedHeight = Math.ceil(width / aspect); return ( <div data-selector="cutting-svg-container" style={{ position: 'relative', overflow: 'visible', height: '1px', }} > <svg style={{ overflow: 'visible' }} className={className} preserveAspectRatio={preserveAspectRatio} viewBox={`0 0 ${width} ${adjustedHeight}`} ref={innerRef} > {children} </svg> </div> ); }
The above component makes use of my useParentSize hook that uses a ResizeObserver to watch for changes in a container <div/>
element. Any time a change of dimensions happens in the target <div />
, a resize event raises new width and height values and the component will re-render in terms of these new values.
To ensure our SVG element keeps its shape at different sizes, we need to calculate its height in terms of its width. This proportional relationship is known as the aspect ratio.
Aspect ratio
Aspect ratio is the ratio of width to height of an image on a screen.
A square image has an aspect ratio of 1:1
. An image that is twice as tall as it is wide has an aspect ratio of 1:2
.
The calculation for the adjusted height is:
const aspect = width / height; const adjustedHeight = Math.ceil(width / aspect);
These values help us complete the viewBox
:
<svg style={{ overflow: 'visible' }} className={className} preserveAspectRatio={preserveAspectRatio} viewBox={`0 0 ${width} ${adjustedHeight}`} ref={innerRef} >
The preserveAspectRatio
attribute
The viewBox
attribute has a sidekick, preserveAspectRatio
. It does not have any effect unless the viewBox exists. The preserveAspectRatio
describes how an SVG document should scale if the aspect ratio of the viewBox
does not match the aspect ratio of the viewPort. Most of the time, the default behavior works, which is:
preserveAspectRatio="xMidYMid meet"
xMidYMid meet
is a bit like the CSS rule background-size: contain;
. A slice
value will scale the image to fit the more generous dimensions and slice off the extra.
preserveAspectRatio="xMidYMid slice"
The slice
value is analogous to the overflow: hidden
CSS rule.
Epilogue
With my ResponsiveSVG
component, I am armed and ready for any device userland can throw at me, and below is how it looks when I resize my browser to something minimal:
LogRocket: Full visibility into your production React apps
Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time,
try LogRocket.
LogRocket
combines session replay, product analytics, and error tracking – empowering software teams to create the ideal web and mobile product experience. What does that mean for you?
Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay problems as if they happened in your own browser to quickly understand what went wrong.
No more noisy alerting. Smart error tracking lets you triage and categorize issues, then learns from this. Get notified of impactful user issues, not false positives. Less alerts, way more useful signal.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your React apps —
start monitoring for free.
Привет, я отчаянно пытаюсь изменить размер SVG в React.
Независимо от того, что я делаю, размер остается неизменным, даже если содержащий его div намного меньше.
В нормальных html и css он будет автоматически изменяться, что я делаю не так?
import React, { Component } from 'react';
import logo from './logo.svg'
class Logo extends Component {
render(){
return(
<div className = "size">
<img src = {logo} alt = {"logo"}/>
</div>
);
}
}
export default Logo
Svg часть
<svg xmlns = "http://www.w3.org/2000/svg" width = "100%" height = "100%" preserveAspectRatio = "none">
<g transform = "translate(0,0)">
<title>Logo</title>
<path fill = "#009FE3" d = "M36.9 707.8H1747V1000H36.9"/>
<path d = "M385 104.1h1.7l138.7 503.5h86.3L771.6.1h-90.5L567.7 494.2H566L429.8.1h-89.7L203.9 494.2h-1.7L88.8.1H0l158.3 607.5h86.2m889.6-119.4c-16.2 22.1-35.4 38.8-57.7 50.3-22.3 11.5-47 17.3-74.2 17.3-12 .2-26.4-2.9-43.3-9.2-16.9-6.3-31.9-16.8-45-31.5-13.1-14.7-20-34.7-20.8-59.9.3-31.5 9.5-56.9 27.6-76.1 18.1-19.2 43.6-38.7 76.4-58.3l137 167.4zm-110.9-252.1c-12.5-11.9-25.4-27.4-38.6-46.5-13.2-19.1-20.4-38.8-21.5-59.2-.3-7.2 1.2-15.9 4.5-26.1 3.3-10.2 10.1-19.3 20.3-27.3 10.2-8 25.6-12.1 46.2-12.6 13.5-.6 27.4 3.8 41.8 13.1 14.4 9.3 22.2 27.2 23.4 53.7-1.2 25.6-9.8 46.7-26 63.5-16.1 16.9-32.8 30.7-50.1 41.4zm195.5 240.3c15.5-29 27.2-56.8 35-83.4 7.8-26.6 12.5-50.4 14.1-71.4h-70.2c-3.5 21.2-6.9 38-10 50.2-3.2 12.2-8 27.1-14.5 44.5l-110.8-132c15.5-10 31.5-21.9 48.2-35.8 16.7-13.9 30.9-30.8 42.6-50.8 11.7-20 17.8-44.1 18.3-72.4.3-31.8-10.4-60.3-32.2-85.4-21.8-25.1-56.4-38.3-103.9-39.8-46.7 1.3-82.3 15-106.8 41.3-24.5 26.3-36.8 57.6-37 94-.1 25.2 5.2 47.4 15.7 66.6 10.5 19.2 26.7 41.9 48.6 67.9-54.9 30.5-91.8 60-110.7 88.3-18.9 28.3-27.6 62.6-26.3 102.9-.6 16.6 3.6 37.2 12.6 61.9 9 24.7 26.4 46.7 52.3 66.2 25.8 19.5 63.7 29.8 113.5 30.9 43.6-.5 79-8.2 106.1-23.3 27.1-15 50.7-34.6 70.6-58.8l56.7 69.3h96.4l-108.3-130.9zm70.1-403.7h205.6v534.8h82V72.7H1782V0h-493.2"/>
<path fill = "#FFF" d = "M343.3 821.9h-24.1L305.3 886h-.3l-13.4-64.1h-23.7L255.4 886h-.4l-13.9-64.1h-24.9l25.1 89.2h24.1l13.9-65h.4l13.9 65h24.1m192.6-89.2h-24.1L472.3 886h-.3l-13.4-64.1H435L422.4 886h-.3l-13.9-64.1h-25.1l25.2 89.2h24.2l13.9-65h.3l13.9 65h24.1m192.7-89.2h-24.1L639.4 886h-.4l-13.5-64.1h-23.6L589.3 886h-.3l-13.9-64.1h-25l25.2 89.2h24.1l13.9-65h.3l13.9 65h24.2m69.3-24.5h25.1V911H721zm109.4 24.5h23.4c3.2-15.3 5.8-27.8 7.8-37.6 2-9.7 3.7-17.7 4.9-23.9 1.3-6.2 2.3-11.8 3.2-16.6.9-4.9 1.7-10.1 2.6-15.7h.3c1 5.6 1.9 11 2.9 16.1.9 5.1 2 10.9 3.3 17.3 1.3 6.5 2.9 14.5 4.9 24.1 2 9.6 4.5 21.7 7.6 36.3h24.1l33.8-120.2h-25.5c-3.9 16.4-7 29.7-9.4 40-2.4 10.3-4.2 18.5-5.5 24.5-1.3 6-2.3 10.7-3 14.2-.7 3.5-1.3 6.5-1.7 9.2h-.3c-.6-3.7-1.3-7.4-2-11-.7-3.6-1.6-8.3-2.7-14-1.2-5.7-2.8-13.5-4.9-23.5-2.1-10-4.9-23.1-8.4-39.4h-26.6c-3.2 15.6-5.7 28.5-7.7 38.6-2 10.1-3.5 18.2-4.7 24.3-1.1 6.1-2 11.1-2.7 14.8-.7 3.8-1.2 7.2-1.7 10.2h-.3c-.5-3.3-1.1-6.7-1.7-10.3-.7-3.6-1.6-8.3-2.9-14.1-1.2-5.9-3-13.8-5.3-23.9-2.3-10.1-5.4-23.3-9.2-39.6h-26.8l34.2 120.2zm246.9-89.2h-23.4v51.4c-.3 7.8-2.3 13.2-6.2 16.1-3.8 2.9-7.8 4.3-11.9 4.2-3.8.2-7.2-.9-10.3-3.1-3.1-2.2-4.7-6.7-4.9-13.4v-55.3h-23.4v58.6c.2 11.3 3 19.6 8.6 24.9 5.5 5.3 12.8 7.9 21.7 7.9 6.2 0 11.6-1.3 16.2-3.9s8.2-6.2 10.9-11h.3v12.5h22.4v-88.9zm111.6-9.9h36.3v-21.3h-97.8V812h36.3v99.1h25.2m69.7-24.5h25.1V911h-25.1zm165.1-95.9h-23.4v42.7h-.3c-1.7-3.1-4.6-6.1-8.6-9.1s-9.7-4.6-17.2-4.8c-6.6 0-12.7 1.7-18.3 5-5.6 3.4-10.1 8.4-13.5 15.2-3.4 6.8-5.1 15.3-5.2 25.6 0 8.3 1.3 16.1 3.8 23.3 2.6 7.2 6.6 13.1 12.2 17.6 5.5 4.5 12.7 6.8 21.5 7 5 .1 9.8-.9 14.4-3s8.4-5.6 11.4-10.5h.3V911h22.9V790.7zm-62.5 76.5c-.1-7.3 1.4-13.6 4.4-18.9 3-5.3 8.2-8.1 15.6-8.4 5.3.1 9.4 1.5 12.4 4.3 2.9 2.8 5 6.3 6.1 10.6 1.1 4.3 1.7 8.9 1.7 13.8.1 6.9-1.5 12.8-4.8 17.8s-8.6 7.6-16 7.9c-5-.2-8.9-1.7-11.7-4.6-2.8-3-4.8-6.5-5.9-10.6-1.3-4.4-1.9-8.2-1.8-11.9zm172.4 17.7c-1 3.2-3 5.6-5.8 7.3-2.8 1.6-5.9 2.5-9.3 2.5-6.2-.1-10.8-1.5-13.7-4.2-2.9-2.6-4.8-5.6-5.7-9-.9-3.4-1.4-6.3-1.5-8.6h61.1v-4.2c-.2-13.4-2.5-23.7-6.9-30.8-4.4-7.1-9.8-12-16.2-14.6s-12.6-3.8-18.7-3.7c-9.7.2-17.4 2-23.1 5.5-5.8 3.5-10 7.9-12.8 13-2.8 5.1-4.7 10.1-5.5 15-.9 4.9-1.3 8.7-1.2 11.6.3 18.1 4.5 30.8 12.8 38.1 8.2 7.3 18.8 10.9 31.6 10.6 5.2.1 10.4-.8 15.6-2.6 5.2-1.8 9.9-4.8 14.1-8.9 4.2-4.2 7.4-9.8 9.5-16.9l-24.3-.1zm-35.3-27.2c.7-5.9 2.5-10.5 5.5-13.8 3-3.3 7.2-5 12.8-5 4-.1 7.8 1.2 11.4 4 3.6 2.8 5.9 7.7 6.7 14.8h-36.4z"/>
</g>
</svg>
Css часть
body
{
margin: 0;
height: 100%;
overflow: hidden
}
.wrapper
{
min-width: 320px;
max-width: 4096px;
width: 100%;
height: calc(100vh - 0.4vw);
float:left;
}
.size
{
width:100px;
}
Перейти к ответу
Данный вопрос помечен как решенный
Ответы
6
Привет, я не уверен, как ваш веб-пакет настроен для разрешения модулей. Но вот решение для вашего случая:
import React, { Component } from 'react';
import logo from './logo.svg'
const SvgIcon = () => (<svg xmlns = "http://www.w3.org/2000/svg" width = "100%" height = "100%" preserveAspectRatio = "none">
<g transform = "translate(0,0)">
<title>Logo</title>
<path fill = "#009FE3" d = "M36.9 707.8H1747V1000H36.9" />
<path d = "M385 104.1h1.7l138.7 503.5h86.3L771.6.1h-90.5L567.7 494.2H566L429.8.1h-89.7L203.9 494.2h-1.7L88.8.1H0l158.3 607.5h86.2m889.6-119.4c-16.2 22.1-35.4 38.8-57.7 50.3-22.3 11.5-47 17.3-74.2 17.3-12 .2-26.4-2.9-43.3-9.2-16.9-6.3-31.9-16.8-45-31.5-13.1-14.7-20-34.7-20.8-59.9.3-31.5 9.5-56.9 27.6-76.1 18.1-19.2 43.6-38.7 76.4-58.3l137 167.4zm-110.9-252.1c-12.5-11.9-25.4-27.4-38.6-46.5-13.2-19.1-20.4-38.8-21.5-59.2-.3-7.2 1.2-15.9 4.5-26.1 3.3-10.2 10.1-19.3 20.3-27.3 10.2-8 25.6-12.1 46.2-12.6 13.5-.6 27.4 3.8 41.8 13.1 14.4 9.3 22.2 27.2 23.4 53.7-1.2 25.6-9.8 46.7-26 63.5-16.1 16.9-32.8 30.7-50.1 41.4zm195.5 240.3c15.5-29 27.2-56.8 35-83.4 7.8-26.6 12.5-50.4 14.1-71.4h-70.2c-3.5 21.2-6.9 38-10 50.2-3.2 12.2-8 27.1-14.5 44.5l-110.8-132c15.5-10 31.5-21.9 48.2-35.8 16.7-13.9 30.9-30.8 42.6-50.8 11.7-20 17.8-44.1 18.3-72.4.3-31.8-10.4-60.3-32.2-85.4-21.8-25.1-56.4-38.3-103.9-39.8-46.7 1.3-82.3 15-106.8 41.3-24.5 26.3-36.8 57.6-37 94-.1 25.2 5.2 47.4 15.7 66.6 10.5 19.2 26.7 41.9 48.6 67.9-54.9 30.5-91.8 60-110.7 88.3-18.9 28.3-27.6 62.6-26.3 102.9-.6 16.6 3.6 37.2 12.6 61.9 9 24.7 26.4 46.7 52.3 66.2 25.8 19.5 63.7 29.8 113.5 30.9 43.6-.5 79-8.2 106.1-23.3 27.1-15 50.7-34.6 70.6-58.8l56.7 69.3h96.4l-108.3-130.9zm70.1-403.7h205.6v534.8h82V72.7H1782V0h-493.2" />
<path fill = "#FFF" d = "M343.3 821.9h-24.1L305.3 886h-.3l-13.4-64.1h-23.7L255.4 886h-.4l-13.9-64.1h-24.9l25.1 89.2h24.1l13.9-65h.4l13.9 65h24.1m192.6-89.2h-24.1L472.3 886h-.3l-13.4-64.1H435L422.4 886h-.3l-13.9-64.1h-25.1l25.2 89.2h24.2l13.9-65h.3l13.9 65h24.1m192.7-89.2h-24.1L639.4 886h-.4l-13.5-64.1h-23.6L589.3 886h-.3l-13.9-64.1h-25l25.2 89.2h24.1l13.9-65h.3l13.9 65h24.2m69.3-24.5h25.1V911H721zm109.4 24.5h23.4c3.2-15.3 5.8-27.8 7.8-37.6 2-9.7 3.7-17.7 4.9-23.9 1.3-6.2 2.3-11.8 3.2-16.6.9-4.9 1.7-10.1 2.6-15.7h.3c1 5.6 1.9 11 2.9 16.1.9 5.1 2 10.9 3.3 17.3 1.3 6.5 2.9 14.5 4.9 24.1 2 9.6 4.5 21.7 7.6 36.3h24.1l33.8-120.2h-25.5c-3.9 16.4-7 29.7-9.4 40-2.4 10.3-4.2 18.5-5.5 24.5-1.3 6-2.3 10.7-3 14.2-.7 3.5-1.3 6.5-1.7 9.2h-.3c-.6-3.7-1.3-7.4-2-11-.7-3.6-1.6-8.3-2.7-14-1.2-5.7-2.8-13.5-4.9-23.5-2.1-10-4.9-23.1-8.4-39.4h-26.6c-3.2 15.6-5.7 28.5-7.7 38.6-2 10.1-3.5 18.2-4.7 24.3-1.1 6.1-2 11.1-2.7 14.8-.7 3.8-1.2 7.2-1.7 10.2h-.3c-.5-3.3-1.1-6.7-1.7-10.3-.7-3.6-1.6-8.3-2.9-14.1-1.2-5.9-3-13.8-5.3-23.9-2.3-10.1-5.4-23.3-9.2-39.6h-26.8l34.2 120.2zm246.9-89.2h-23.4v51.4c-.3 7.8-2.3 13.2-6.2 16.1-3.8 2.9-7.8 4.3-11.9 4.2-3.8.2-7.2-.9-10.3-3.1-3.1-2.2-4.7-6.7-4.9-13.4v-55.3h-23.4v58.6c.2 11.3 3 19.6 8.6 24.9 5.5 5.3 12.8 7.9 21.7 7.9 6.2 0 11.6-1.3 16.2-3.9s8.2-6.2 10.9-11h.3v12.5h22.4v-88.9zm111.6-9.9h36.3v-21.3h-97.8V812h36.3v99.1h25.2m69.7-24.5h25.1V911h-25.1zm165.1-95.9h-23.4v42.7h-.3c-1.7-3.1-4.6-6.1-8.6-9.1s-9.7-4.6-17.2-4.8c-6.6 0-12.7 1.7-18.3 5-5.6 3.4-10.1 8.4-13.5 15.2-3.4 6.8-5.1 15.3-5.2 25.6 0 8.3 1.3 16.1 3.8 23.3 2.6 7.2 6.6 13.1 12.2 17.6 5.5 4.5 12.7 6.8 21.5 7 5 .1 9.8-.9 14.4-3s8.4-5.6 11.4-10.5h.3V911h22.9V790.7zm-62.5 76.5c-.1-7.3 1.4-13.6 4.4-18.9 3-5.3 8.2-8.1 15.6-8.4 5.3.1 9.4 1.5 12.4 4.3 2.9 2.8 5 6.3 6.1 10.6 1.1 4.3 1.7 8.9 1.7 13.8.1 6.9-1.5 12.8-4.8 17.8s-8.6 7.6-16 7.9c-5-.2-8.9-1.7-11.7-4.6-2.8-3-4.8-6.5-5.9-10.6-1.3-4.4-1.9-8.2-1.8-11.9zm172.4 17.7c-1 3.2-3 5.6-5.8 7.3-2.8 1.6-5.9 2.5-9.3 2.5-6.2-.1-10.8-1.5-13.7-4.2-2.9-2.6-4.8-5.6-5.7-9-.9-3.4-1.4-6.3-1.5-8.6h61.1v-4.2c-.2-13.4-2.5-23.7-6.9-30.8-4.4-7.1-9.8-12-16.2-14.6s-12.6-3.8-18.7-3.7c-9.7.2-17.4 2-23.1 5.5-5.8 3.5-10 7.9-12.8 13-2.8 5.1-4.7 10.1-5.5 15-.9 4.9-1.3 8.7-1.2 11.6.3 18.1 4.5 30.8 12.8 38.1 8.2 7.3 18.8 10.9 31.6 10.6 5.2.1 10.4-.8 15.6-2.6 5.2-1.8 9.9-4.8 14.1-8.9 4.2-4.2 7.4-9.8 9.5-16.9l-24.3-.1zm-35.3-27.2c.7-5.9 2.5-10.5 5.5-13.8 3-3.3 7.2-5 12.8-5 4-.1 7.8 1.2 11.4 4 3.6 2.8 5.9 7.7 6.7 14.8h-36.4z" />
</g>
</svg>)
class Logo extends Component {
render() {
return (
<div style = {{height:'200px',
width: '500px'}} className = "size">
<SvgIcon />
</div>
);
}
}
export default Logo
Вы должны сделать:
import logo from './logo.svg'
const Logo = () => {
return (
<logo height='200px' width='500px' alt = "tuvieja"/>
);
}
}
Попробуйте это, он будет работать отлично.
import Logo from "./logo.svg";
<img
src = {Logo}
style = {{ height: 53, width: 36 }}
alt = "website logo"
/>
Если вы импортируете файл SVG как компонент:
import { ReactElement as ComponentName } from "./file.svg"
Вы можете изменить размер с помощью CSS transform: scale(2) в <ComponentName />, чего в React можно добиться с помощью className или глобального файла CSS.
Примечание. Чтобы изменить цвет, вы можете использовать .componentClass path { fill: «color» }, но если вы измените масштаб на .componentClass path, это не будет выглядеть круто, даже если вы измените width и height в компоненте .componentClass, что фактически изменит размер контейнера SVG, а не размер. содержание…
Откройте файл SVG в текстовом редакторе и удалите атрибуты width и height из корневого узла.
Это легко сделать, отредактировав соответствующий код SVG напрямую. См. Ниже:
<svg id = "_x31_" enable-background = "new 0 0 24 24" height = "250" viewBox = "0 0 24 24" width = "250" xmlns = "http://www.w3.org/2000/svg"><path d = "m20.5 18h-6c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h6c.276 0 .5.224.5.5s-.224.5-.5.5z"/><path d = "m13.5 9h-10c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h10c.276 0 .5.224.5.5s-.224.5-.5.5z"/><path d = "m10.5 12h-7c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h7c.276 0 .5.224.5.5s-.224.5-.5.5z"/><path d = "m8.5 15h-5c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h5c.276 0 .5.224.5.5s-.224.5-.5.5z"/></svg>
Вам нужно только изменить атрибуты высота и ширина соответственно.
Другие вопросы по теме
At Vandebron we’re maintaining a component library called Windmolen (Dutch for «wind turbine»). And if you’ve ever built a component library, you probably dealt with optimizing and converting icons before. With SVGO and SVGR you can do this at scale, without compromising the quality or size of your icons.
The problem
The web is full of icons, and often these icons are rendered from SVG files to ensure you can increase (or decrease) the size of the icons depending on the use case. Designers often create these icons from design tools like Adobe Photoshop or Sketch. Although these icons might look pretty, exporting a SVG out of these tools is often difficult as this article explains. Also, added lot of code in the form of metadata is added to the SVG file. Let’s have a look at what a typical SVG file exported out of Sketch looks like:
<!-- something.svg -->
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 46 (44423) - http://www.bohemiancoding.com/sketch -->
<title>last</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="last" transform="translate(2.000000, 0.000000)" fill-rule="nonzero" fill="#666666">
<polygon id="Fill-2" points="6.6902923 9.6812703 9.3700469 7.0005052 6.6902923 4.3187297 2.37257308 0 0 2.37358354 4.3177192 6.6902923 4.6279322 7.0005052 4.3177192 7.3107182 0 11.6274269 2.37257308 14"></polygon>
</g>
</g>
</svg>
Enter fullscreen mode
Exit fullscreen mode
The SVG file above holds a lot of information about Sketch, such as the title
of the icon and a desc
ription. Next to that, there’s a lot of elements that could be combined into one element to reduce the file size.
Optimizing SVGs
What’s cool about SVG files is that you can optimize and minify them, without affecting what the SVG looks like. This is something you can try out yourself using the website SVGOMG, which is powered by the library SVGO that you’ll learn more about later.
You can optimize the SVG file above by following these steps:
- Go to https://jakearchibald.github.io/svgomg/
- Click on
Paste markup
an paste the SVG code that you exported from Sketch (a.k.a. the SVG file above) - You will see the icon rendered, now you have to either click at the
Copy as a text
orDownload
button to get the optimized SVG file
With these simple steps you’ve optimized the SVG from over 450 bytes, which is already small, to 173 bytes (a decrease of over 38%!). If you’d open this file in the editor of your choice, you can see a lot of the useless (meta)data from the original file has been deleted. Also, the different elements of the SVG are combined in a single path
that renders the icon:
<!-- something.svg -->
<svg width="14" height="14" xmlns="http://www.w3.org/2000/svg">
<path d="M8.69 9.681l2.68-2.68-2.68-2.682L4.373 0 2 2.374 6.318 6.69l.31.31-.31.31L2 11.628 4.373 14z" fill-rule="nonzero" fill="#666"/>
</svg>
Enter fullscreen mode
Exit fullscreen mode
This SVG can be even further optimized by checking the «Prefer viewbox to width/height» in SVGOMG, but let’s save that for later when we use SVGO instead.
Using SVGO
By using SVGOMG you’ve already experienced what power SVGO has, as SVGOMG is described by its creators as » SVGO’s Missing GUI, aiming to expose the majority if not all the configuration options of SVGO». Instead of using the GUI, you can also use SVGO directly from the command line as a CLI-tool or as a Node.js module. For the sake of this article, we’ll be using it solely as CLI.
SVGO can be installed globally on your machine, or locally in your project, from npm by running:
npm i -g svgo
# Yarn equivalent
yarn add -G svgo
Enter fullscreen mode
Exit fullscreen mode
After doing this you can run svgo
from the command line and optimize any SVG file instantly. But, you don’t want to do this manually on your machine anytime you’re adding a new icon to a project (or component library). Therefore, you can also add SVGO to a project locally and add a script to the package.json
file to optimize all SVGs in a certain directory.
// package.json
{
// ...
"scripts": {
// ...
"optimize-svg": "svgo --config=.svgo.yml -f ./src/assets/icons"
}
}
Enter fullscreen mode
Exit fullscreen mode
The optimize-svg
script will run SVGO in the directory src/assets/icons
and optimize all the SVG files based on the settings in .svgo.yml
. This file is where you can configure the rules for SVGO, as the previously mentioned «Prefer viewbox to width/height»:
# .svgo.yml
plugins:
- removeViewBox: false
- removeDimensions: true # this deletes width/height and adds it to the viewBox
- removeDoctype: true
- removeComments: true
- removeMetadata: true
- removeEditorsNSData: true
- cleanupIDs: true
- removeRasterImages: true
- removeUselessDefs: true
- removeUnknownsAndDefaults: true
- removeUselessStrokeAndFill: true
- removeHiddenElems: true
- removeEmptyText: true
- removeEmptyAttrs: true
- removeEmptyContainers: true
- removeUnusedNS: true
- removeDesc: true
- prefixIds: false
- prefixClassNames: false
Enter fullscreen mode
Exit fullscreen mode
From the rules above you’ll get an idea about all the redundant and useless lines of code that might be present in your SVG files. But luckily, they will all get removed when you run the command npm run optimize-svg
.
Converting SVGs with SVGR
You’ve now learned how to optimize your SVG files, and are probably wondering how to use these files in a React application. To render an SVG in React, you need to either configure Webpack in a way that it knows how to deal with SVG files or use a library called SVGR. By default, any application created with create-react-app
can render SVG files as a component, using the following import
statement:
// MyComponent.jsx
import React from 'react';
import { ReactComponent as MySVG } from './something.svg';
const MyComponent = () => {
return (
<div>
<MySVG />
</div>
);
}
export default MyComponent;
Enter fullscreen mode
Exit fullscreen mode
More information about how this is done can be found in this article, but let me show you how to solve that with SVGR.
With SVGR you can convert SVG files into React Components, either by adding it to Webpack or by using the SVGR CLI or Node.js module. In the same way, as we optimized the SVGs from the command line with SVGO, we can also convert these icons from the command line with SVGR:
// package.json
{
// ...
"scripts": {
// ...
"optimize-svg": "svgo --config=.svgo.yml -f ./src/assets/icons",
"convert-svg": "svgr -d ./src/components/Icon ./src/assets/icons"
}
}
Enter fullscreen mode
Exit fullscreen mode
Whenever you run the command npm run convert-svg
a JSX file will be created for every SVG file that’s present in the directory src/assets/icons
. These JSX files can be found in the directory src/components/Icons
, together with an index.js
file that exports all these components from this directory.
An example of such a converted SVG file is:
// MySVG.jsx
import * as React from 'react';
const MySVG = (props) => (
<svg viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" {...props}>
<path d="M8.69 9.681l2.68-2.68-2.68-2.682L4.373 0 2 2.374 6.318 6.69l.31.31-.31.31L2 11.628 4.373 14z" fill-rule="nonzero" fill="#666"/>
</svg>
);
export default MySVG;
Enter fullscreen mode
Exit fullscreen mode
And, as we now have a directory filled with converted SVGs these can be imported into any React component like this:
// MyComponent.jsx
import React from 'react';
import MySVG from './MySVG.jsx';
const MyComponent = () => {
return (
<div>
<MySVG />
</div>
);
}
export default MyComponent;
Enter fullscreen mode
Exit fullscreen mode
Often SVGR is used alongside SVGO, so you can even automatically optimize all SVGS that will be converted by SVGR. This is done by adding the flag --no-svgo true
and point it towards your SVGO configuration file:
// package.json
{
// ...
"scripts": {
// ...
"convert-svg": "svgr -d ./src/components/Icon ./src/assets/icons --no-svgo true --svgo-config .svgo.yml"
}
}
Enter fullscreen mode
Exit fullscreen mode
By running the convert-svg
script you both optimize and convert all the SVG files in src/assets/icons
to React components based on optimized SVGs.
Reading further
The examples in this post are the tip of the metaphorical iceberg on what problems SVGO and SVGR can solve. There are many other features you can enable, such as using them as Node.js modules or enabling TypeScript support. To read further make sure to have a look at the SVGR playground or documentation.