В svg спрайте изменять размер определенного куска не получится, если не менять background-size для спрайта и width и height для отдельного взятого svg. Есть
прекрасная статья, материалы которой я использовал у себя. На этой неделе решил собирать svg-спрайты папками (раньше папками собирались только png), иконок было много, дизайнер нарисовал размеры больше чем нужно, менять размер каждой иконки слишком рутинно. Реализовал миксины (mixin svg-sprite это mixin sprite из вышеуказанной статьи):
// svg из папки генерируют scss файлы {название_папки}.scss
@import '../sprites/svg.scss',
'../sprites/ne-svg.scss';
// список спрайтов помещаем в массив
$svg-sprites: (svg: $svg-icons, ne-svg: $ne-svg-icons);
$svg-sprite: map-get($svg-icons, sprite) !default;
$ne-svg-sprite: map-get($ne-svg-icons, sprite) !default;
// Gets an attribute from the sass map
@function sprite-attr($icon, $attr, $sprite) {
$newIcon: map-get($sprite, $icon);
@if $newIcon == null {
@warn "Can't find an icon with the name #{$icon}";
}
@return map-get($newIcon, $attr);
}
@function icon-attr($icon, $sprite) {
$sprite: map-get($svg-sprites, $sprite);
$attr: (
width: sprite-attr($icon, width, $sprite),
height: sprite-attr($icon, height, $sprite),
x: sprite-attr($icon, backgroundX, $sprite),
y: sprite-attr($icon, backgroundY, $sprite)
);
@return $attr;
}
%svg-sprite {
display: inline-block;
background-image: url(map-get($svg-sprite, svgPath));
background-size: map-get($svg-sprite, width) map-get($svg-sprite, height);
}
%ne-svg-sprite {
display: inline-block;
background-image: url(map-get($ne-svg-sprite, svgPath));
background-size: map-get($ne-svg-sprite, width) map-get($ne-svg-sprite, height);
}
@mixin ne-svg-bg-size($percent: 100) {
$bg-size-x: map-get($ne-svg-sprite, width);
$bg-size-y: map-get($ne-svg-sprite, height);
background-size: round($bg-size-x * $percent / 100) round($bg-size-y * $percent / 100);
}
@mixin svg-sprite($icon, $type: all, $sprite: svg) {
@if $type == all {
// Shares the backgrounds
@extend %#{$sprite}-sprite;
}
$iconMap: icon-attr($icon, $sprite);
// Outputs dimensions in em
@if $type == all or $type == size {
width: map-get($iconMap, width);
height: map-get($iconMap, height);
}
// Outputs background position in px
@if $type == all or $type == bg {
background-position: map-get($iconMap, x) map-get($iconMap, y);
}
}
@mixin svg-sprite-percent($icon, $type: all, $sprite: svg, $percent: 100) {
@if $percent == 100 {
@include svg-sprite-percent($icon, $type, $sprite);
} @else {
@if $type == all {
// Shares the backgrounds
@extend %#{$sprite}-sprite;
@include ne-svg-bg-size($percent);
}
$iconMap: icon-attr($icon, $sprite);
@if $type == all or $type == size {
width: round(map-get($iconMap, width) * $percent / 100);
height: round(map-get($iconMap, height) * $percent / 100);
}
@if $type == all or $type == bg {
background-position: round(map-get($iconMap, x) * $percent / 100) round(map-get($iconMap, y) * $percent / 100);
}
}
}
Использую такой шаблон для генерации файла scss, (параметр common: folderName указывается в сборке gulp-svg-sprite)
// {{date}}
${{common}}-icons: (
sprite: (width: {{spriteWidth}}px, height: {{spriteHeight}}px, pngPath: '/source/i/{{common}}-sprite.png', svgPath: '/source/i/{{common}}-sprite.svg'),
{{#shapes}}
{{base}}: (width: {{width.inner}}px, height: {{height.inner}}px, backgroundX: {{position.absolute.x}}px, backgroundY: {{position.absolute.y}}px),
{{/shapes}});
А использую это примерно так (в папке ne-svg находятся файлы file-gray.svg, help-gray.svg, hand-icon.svg):
$icons: (file: file-gray, help: help-gray, touch: hand-icon);
@each $i, $icon in $icons {
.icon--#{$i} {
@extend %ne-svg-sprite;
@include svg-sprite-percent($icon, all, ne-svg, 66);
}
}
Возможно написал избыточную информацию, но мне кажется мой опыт будет полезным еще кому-то, хотя не претендую на звание изящного решения. По любым вопросам готов помочь.