Johnson Cherian
Johnson Cherian

Reputation: 643

Use material ui svg icons as background image

Can I use @material-ui/icons svg images as background of other elements.? Tried the below code but didn't work.

import CarIcon from '@material-ui/icons/DriveEtaRounded';

const carIcon = <CarIcon />

function Cover(){
  return (
    <div
        className={classes.cover}
        style={{ backgroundImage: 'url('+ carIcon+')' }}
    />
  )
}

Upvotes: 8

Views: 11191

Answers (2)

coot3
coot3

Reputation: 632

Based on an example from the MUI docs relating to custom switches, you can set the backgroundImage property to an Mui icon using the following format:

backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20">
  <path fill="${encodeURIComponent('#fff',)}" 
  d="M4.2 2.5l-.7 1.8-1.8.7 1.8.7.7 1.8.6-1.8L6.7 5l-1.9-.7-.6-1.8zm15 8.3a6.7 6.7 0 11-6.6-6.6 5.8 5.8 0 006.6 6.6z"/>
</svg>')`,

It's messy because you can't just use CarIcon, you need the actual svg path (the d attribute in above example). To get the d value of the svg I wanted to use, I just found the icon's file in node modules (e.g node_modules > @mui > icons-material > DriveEtaRounded.js):

DriveEtaRound.js:

"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _createSvgIcon = _interopRequireDefault(require("./utils/createSvgIcon"));

var _jsxRuntime = require("react/jsx-runtime");

var _default = (0, _createSvgIcon.default)( /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
//
// ----  d value here \/
// 
  d: "M18.92 5.01C18.72 4.42 18.16 4 17.5 4h-11c-.66 0-1.21.42-1.42 1.01l-1.97 5.67c-.07.21-.11.43-.11.66v7.16c0 .83.67 1.5 1.5 1.5S6 19.33 6 18.5V18h12v.5c0 .82.67 1.5 1.5 1.5.82 0 1.5-.67 1.5-1.5v-7.16c0-.22-.04-.45-.11-.66l-1.97-5.67zM6.5 15c-.83 0-1.5-.67-1.5-1.5S5.67 12 6.5 12s1.5.67 1.5 1.5S7.33 15 6.5 15zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 10l1.27-3.82c.14-.4.52-.68.95-.68h9.56c.43 0 .81.28.95.68L19 10H5z"
//
// ----  d value here /\
// 
}), 'DriveEtaRounded');

exports.default = _default;

So your end result should be:

backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20">
  <path fill="${encodeURIComponent('#fff',)}" 
  d="M18.92 5.01C18.72 4.42 18.16 4 17.5 4h-11c-.66 0-1.21.42-1.42 1.01l-1.97 5.67c-.07.21-.11.43-.11.66v7.16c0 .83.67 1.5 1.5 1.5S6 19.33 6 18.5V18h12v.5c0 .82.67 1.5 1.5 1.5.82 0 1.5-.67 1.5-1.5v-7.16c0-.22-.04-.45-.11-.66l-1.97-5.67zM6.5 15c-.83 0-1.5-.67-1.5-1.5S5.67 12 6.5 12s1.5.67 1.5 1.5S7.33 15 6.5 15zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 10l1.27-3.82c.14-.4.52-.68.95-.68h9.56c.43 0 .81.28.95.68L19 10H5z"/>
</svg>')`,

make sure you use d="... and not d:"...

Upvotes: 1

@material-ui/icons are React components and if you open their source, they contain only SVG data that are encapsulated in <svg> tag using a utility function. However you can simulate background-image behaviour by using them directly and a bit of styling:

import CarIcon from '@material-ui/icons/DriveEtaRounded';

function Cover(){
  return (
    <div style={{position: 'relative', width: '200px', height: '100px'}}>
      <CarIcon style={{position: 'absolute', left: 0, top: 0, width: '100%', height: '100%'}} />
    </div>
  )
}

This is an example but it will work as long as the parent element has its dimensions set by other content. You can also simulate background-size: cover behaviour by adding preserveAspectRatio='xMidYMid slice' to the icon component (default value corresponds to contain). An added benefit of this approach is that the icons are still SVGs and can be further styled or animated.

Upvotes: 10

Related Questions