Faced a problem with the layout of the site. I have a number of SVG icons that look something like this:

enter image description here

The problem is that around the image itself there are indents to the edges. I would like these indents not to be, because with them every icon when placed in an element has to be customized in size and positioning in css.

I know how to remove these indents with Inkscape. But this is handmade, and a lot of icons.

Is there any utility that can remove these indents automatically? Preferably under Linux (node, python will do).

SVG example: gist

  • 2
    It's not so simple ... - Qwertiy
  • @cronfy Share, please, how is it going with the automation of icon processing. I think it will be interesting to many - Alexandr_TT
  • one
    @Alexandr_T thanks for asking! :) encouraged me to finish this task. I managed to write a script using PhanomJS. I added the answer, and also made a repository on github: github.com/cronfy/svg-padding-remover - cronfy

4 answers 4

Short answer

Here is a script .

It requires PhantomJS and works as follows:

phantomjs svg-padding-remover.js path/to/image.svg > new.svg 

Long answer

You can use PhantomJS to emulate a browser in the command line. Accordingly, all possible browser-based methods are available for SVG manipulations (please read this in the comments for a better link).

I used the answer Qwertiy (thanks for the idea!) To write such a command line script.

If you simplify the script as much as possible (remove the parsing of command line arguments, error handling), and leave only the principle of operation, you get this:

remover.js

 // здесь нужно указать путь до картинки var fs = require('fs'); var url = 'file://' + fs.absolute('1.svg'); // открываем файл svg как документ var page = require('webpage').create(); page.open(url, function () { // Вызов нашей функции, которая будет выполнена // в контексте открытого документа. // Она изменит документ (svg) необходимым нам образом. page.evaluate(svgPaddingRemover); // вывод нового содержимого документа console.log(page.content); // выход phantom.exit(); }); // Функция, которая изменяет документ. // В данном случае - корректирует viewBox, удаляет width и height. var svgPaddingRemover = function () { var svg = document.querySelector("svg"); var svgall = svg.querySelectorAll("*"); var l = Infinity, t = Infinity, r = -Infinity, b = -Infinity; for (i = 0; i < svgall.length; i++) { var elem = svgall[i]; var bb = elem.getBBox(); if (bb.width && bb.height) { l = Math.min(l, bb.x); t = Math.min(t, bb.y); r = Math.max(r, bb.x + bb.width); b = Math.max(b, bb.y + bb.height); } } svg.setAttribute("viewBox", l + ' ' + t + ' ' + (r - l) + ' ' + ' ' + (b - t)); svg.removeAttribute("width"); svg.removeAttribute("height"); }; 

Running the script:

 phantomjs remover.js > cropped-image.svg 
  • But surely in nodejs there are specialized things for svg? - Qwertiy
  • @cronfy, I realized that indents are removed by increasing the size of the icon. Do not interfere in your project? - Alexandr_TT
  • @Alexandr_T, so he wanted it. - Qwertiy
  • @Qwertiy for sure, but I didn’t find any working npm modules, however, I don’t really understand them. If someone tells you which module to use, it will be great, because then it will turn out to translate the script into gulp. - cronfy
  • 2
    @Alexandr_T actually, the task was to process the icons to use in the project To be able to insert them into the container and stretch to the full width, and not to fit the indents. And normal to center. Of course, if the already adjusted icons are processed by the script, the display will go, you need to correct the css after processing and remove unnecessary more offsets. - cronfy

You can quickly remove indents using viewport and viewBox For example, there is such an icon

 <svg version="1" xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96" style="border:1px solid crimson" > <g fill="#00BCD4"> <rect x="37" y="18" width="6" height="24"/> <rect x="29" y="26" width="6" height="16"/> <rect x="21" y="22" width="6" height="20"/> <rect x="13" y="32" width="6" height="10"/> <rect x="5" y="28" width="6" height="14"/> </g> <g fill="#3F51B5"> <circle cx="8" cy="16" r="3"/> <circle cx="16" cy="18" r="3"/> <circle cx="24" cy="11" r="3"/> <circle cx="32" cy="13" r="3"/> <circle cx="40" cy="9" r="3"/> <polygon points="39.1,7.2 31.8,10.9 23.5,8.8 15.5,15.8 8.5,14.1 7.5,17.9 16.5,20.2 24.5,13.2 32.2,15.1 40.9,10.8"/> </g> </svg> 
The red frame around the icon is the viewport scope. These indents are preserved when inserted into html. By changing the attributes viewport and viewBox you can remove indents.
In the example below, the scale is 1: 1, but the viewport is reduced and the indents are almost reduced.

 <svg version="1" xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" style="border:1px solid crimson" > <g fill="#00BCD4"> <rect x="37" y="18" width="6" height="24"/> <rect x="29" y="26" width="6" height="16"/> <rect x="21" y="22" width="6" height="20"/> <rect x="13" y="32" width="6" height="10"/> <rect x="5" y="28" width="6" height="14"/> </g> <g fill="#3F51B5"> <circle cx="8" cy="16" r="3"/> <circle cx="16" cy="18" r="3"/> <circle cx="24" cy="11" r="3"/> <circle cx="32" cy="13" r="3"/> <circle cx="40" cy="9" r="3"/> <polygon points="39.1,7.2 31.8,10.9 23.5,8.8 15.5,15.8 8.5,14.1 7.5,17.9 16.5,20.2 24.5,13.2 32.2,15.1 40.9,10.8"/> </g> </svg> 

If you just need to move the icon inside the viewport you can use the first two attributes viewBox = "12 0 48 48" -shift left. More detail: here and here
If you have the same type of icons, then experimenting with the attributes of the viewport viewBox on one icon, then you can make an viewBox replacement of the attributes of the entire package of icons, for example in notepad ++

  • Thank you for the clarification. Icons, unfortunately, are not exactly the same type. Therefore, a simple autochange will not work. - cronfy
  • @cronfy In the icon that you indicated in the header of the post, you really need to remove indents? By the way, pay attention to the line in my examples - style = "border: 1px solid crimson;" So she reveals indents. - Alexandr_TT
  • This is not an automatic option. - Vadizar
  • @Alexandr_T yes, you need to remove completely, absolutely. To do this: gist.github.com/cronfy/e3b1df6b31c709910a9fd4ce8aab45f0 (here I manually corrected the viewbox and deleted the width and height, and just in case the background). - cronfy
  • @cronfy is great! did everything right - viewBox = "128 56.4 581 468", you also need to remove all the service information that the chandelier leaves xml:space="preserve" it does not affect anything, and the group <g> tags in the current version are superfluous - Alexandr_TT

The simplest option would be something like this:

 document.querySelector("button").addEventListener("click", function () { var svg = document.querySelector("svg"); var l = Infinity, t = Infinity, r = -Infinity, b = -Infinity; for (var elem of svg.querySelectorAll("*")) { var bb = elem.getBBox(); if (bb.width && bb.height) { l = Math.min(l, bb.x); t = Math.min(t, bb.y); r = Math.max(r, bb.x + bb.width); b = Math.max(b, bb.y + bb.height); } } svg.setAttribute("viewBox", `${l} ${t} ${rl} ${bt}`); svg.removeAttribute("width"); svg.removeAttribute("height"); }); 
 p { border: 1px solid blue; } svg { display: block; height: 10em; width: auto; border: 1px solid red; } 
 <p> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" width="836.2px" height="581.1px" viewBox="0 0 836.2 581.1" enable-background="new 0 0 836.2 581.1" xml:space="preserve"> <g> <g> <g> <path d="M440.4,119.9h-1c-6.7,0-12.1,5.4-12.1,12.1s5.4,12.1,12.1,12.1h1c6.7,0,12.1-5.4,12.1-12.1 C452.5,125.3,447.1,119.9,440.4,119.9z"/> <path d="M657.2,249.3c-4.7-4.7-12.4-4.7-17.1,0l-7.8,7.8l-7.8-7.8c-4.7-4.7-12.4-4.7-17.1,0c-4.7,4.7-4.7,12.4,0,17.1l7.8,7.8 l-7.8,7.8c-4.7,4.7-4.7,12.4,0,17.1c2.4,2.4,5.5,3.5,8.6,3.5c3.1,0,6.2-1.2,8.6-3.5l7.8-7.8l7.8,7.8c2.4,2.4,5.5,3.5,8.6,3.5 s6.2-1.2,8.6-3.5c4.7-4.7,4.7-12.4,0-17.1l-7.8-7.8l7.8-7.8C661.9,261.7,661.9,254,657.2,249.3z"/> <path d="M576,249.3c-4.7-4.7-12.4-4.7-17.1,0l-7.8,7.8l-7.8-7.8c-4.7-4.7-12.4-4.7-17.1,0c-4.7,4.7-4.7,12.4,0,17.1l7.8,7.8 l-7.8,7.8c-4.7,4.7-4.7,12.4,0,17.1c2.4,2.4,5.5,3.5,8.6,3.5s6.2-1.2,8.6-3.5l7.8-7.8l7.8,7.8c2.4,2.4,5.5,3.5,8.6,3.5 c3.1,0,6.2-1.2,8.6-3.5c4.7-4.7,4.7-12.4,0-17.1l-7.8-7.8l7.8-7.8C580.8,261.7,580.8,254,576,249.3z"/> <path d="M666.3,149.5H517.7v-41c0-16.7-7.7-32-21.1-41.9c-13.4-9.9-30.3-12.9-46.3-8c-0.2,0.1-0.3,0.1-0.5,0.2l-76.5,27h-64.1 l-76.5-27c-0.2-0.1-0.3-0.1-0.5-0.2c-16-4.9-32.8-1.9-46.3,8c-13.4,9.9-21.1,25.2-21.1,41.9v41.3c-20.9,2.6-37.2,20.4-37.2,42 v290.5c0,23.4,19,42.4,42.4,42.4h496.4c23.4,0,42.4-19,42.4-42.4V191.9C708.7,168.5,689.7,149.5,666.3,149.5z M387.4,144.1h15.1 c6.7,0,12.1-5.4,12.1-12.1s-5.4-12.1-12.1-12.1h-15.1v-13.4l70.1-24.7c8.5-2.5,17.4-0.9,24.6,4.4c7.2,5.3,11.3,13.5,11.3,22.5 v46.9c0,9-4.1,17.1-11.3,22.5c-7.1,5.3-16.1,6.9-24.6,4.4l-70.1-24.7V144.1L387.4,144.1z M373.2,178.2l41.7,14.7l27.1,46.9 l-13.8-2.4c-5.8-1-11.4,2.3-13.5,7.8l-4.8,13.2l-46.3-80.2L373.2,178.2L373.2,178.2z M319.2,110h44v44h-44V110z M321.9,178.2 l-46.3,80.2l-4.8-13.2c-2-5.5-7.7-8.8-13.5-7.8l-13.8,2.4l27.9-48.3l37.7-13.3L321.9,178.2L321.9,178.2z M189,108.5 c0-9,4.1-17.1,11.3-22.5c4.9-3.6,10.7-5.5,16.6-5.5c2.7,0,5.4,0.4,8,1.2l70.1,24.7v13.4h-53c-6.7,0-12.1,5.4-12.1,12.1 c0,6.7,5.4,12.1,12.1,12.1h53v13.4l-70.1,24.7c-8.5,2.5-17.4,0.9-24.6-4.4c-7.2-5.3-11.3-13.5-11.3-22.5V108.5L189,108.5z M684.4,482.4c0,10-8.1,18.2-18.2,18.2H169.9c-10,0-18.2-8.1-18.2-18.2v-35.3h532.7L684.4,482.4L684.4,482.4z M684.4,422.9H151.8 v-60.5h532.7L684.4,422.9L684.4,422.9z M684.4,338.2H151.8V191.9c0-9.4,7.2-17.1,16.3-18.1c3.5,9.2,9.5,17.4,17.8,23.5 c9.2,6.8,19.9,10.3,30.9,10.3c5.1,0,10.3-0.8,15.3-2.3c0.2-0.1,0.3-0.1,0.5-0.2l3.7-1.3l-26.7,46.3c-2.3,4.1-2.1,9.1,0.6,13 c2.7,3.9,7.4,5.8,12,5l29.4-5.1l10.2,28c1.6,4.4,5.6,7.5,10.3,7.9c0.4,0,0.7,0,1,0c4.3,0,8.3-2.3,10.5-6.1l59.1-102.5L402,292.9 c2.2,3.8,6.2,6.1,10.5,6.1c0.3,0,0.7,0,1,0c4.7-0.4,8.7-3.5,10.3-7.9l10.2-28l29.4,5.1c4.6,0.8,9.3-1.1,12-5 c2.7-3.9,2.9-8.9,0.6-13l-25.9-44.9c0.1,0,0.1,0,0.2,0.1c5.1,1.5,10.2,2.3,15.3,2.3c11,0,21.8-3.5,30.9-10.3 c8.3-6.1,14.4-14.3,17.8-23.6h151.9c10,0,18.2,8.1,18.2,18.2L684.4,338.2L684.4,338.2z"/> </g> </g> </g> </svg> </p> <button>Crop</button> 

  • Great, the algorithm is working! And how can this be translated under the node? - cronfy
  • @cronfy, well, somehow it should be possible, but I do not know :) In extreme cases, you can poke phantomjs. - Qwertiy
  • About phantomjs regarding svg generation is mentioned in this article: smashingmagazine.com/2014/05/… , candidate for the role of a starting point. - cronfy
  • Well, sort of happened. See my answer. - cronfy

You can use the plug-ins for Gulp - gulp-imagemin and imagemin-svgo:

 var gulp = require('gulp'), imagemin = require('gulp-imagemin'), imageminSvgo = require('imagemin-svgo'); gulp.task('imagemin', function() { gulp.src('./img/**/*') .pipe(imagemin([ imageminSvgo({ plugins: [ {removeViewBox: true} ] }) ])) .pipe(gulp.dest('./public/img/')) }); 
  • 2
    From the documentation: "remove viewBox attribute when possible (disabled by default)". But after all it is necessary not to delete, but to change. - Qwertiy
  • one
    Thanks, but it didn't help. I added an example of an icon to the question. After processing your code in dest, the exact same icon appears, only minified and without viewbox. But indents do not disappear anywhere :( - cronfy
  • @cronfy sorry, gave the wrong option. Here is a list of all available options, see - github.com/svg/svgo#what-it-can-do . Perhaps you need removeDimensions. - Vadizar
  • one
    @Vadizar I watched this list before asking a question :) remove dimensions just remove the width and height, and to achieve the goal you need to also correct the viewbox. - cronfy