Тень Svg обрезается только при преобразовании родителя с одинаковыми размерами

#html #css #svg

Вопрос:

У меня есть svg, который принимает ширину своего родителя, но когда я масштабирую или поворачиваю родителя, тень svg обрезается. Левый-это нормально, но когда родитель имеет ту же ширину и высоту svg (правый), он ведет себя по-другому. У меня есть видимое переполнение и filterUnits=»userSpaceOnUse» http://jsfiddle.net/xrsknjfv/

 scale.addEventListener("mousedown", function(){
    this.parentElement.classList.toggle("scale");
}) 
 svg{
  fill: yellow;
  overflow: visible;
  width: 100%;
}
body > div{
  position: absolute;
  left: 50px;
  top: 50px;
}
div > div{
  display: inline-block;
  width: 150px;
  transition: 5s all;
}
div > div:nth-of-type(1){
   padding: 15px;
}
div.scale > div{
  transform: scale(0);
} 
 <div>
  <button id="scale">
    scale
  </button>
  <div>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 409.96 254.59">
      <defs>
        <filter filterUnits="userSpaceOnUse" id="f1">
          <feDropShadow filterUnits="userSpaceOnUse" dx="1.5" dy="0.8" stdDeviation="1"></feDropShadow>
        </filter>
        <filter filterUnits="userSpaceOnUse" id="f2">
          <feDropShadow filterUnits="userSpaceOnUse" dx="-2" dy="1.8" stdDeviation="1"></feDropShadow>
        </filter>
        <filter filterUnits="userSpaceOnUse" id="f3">
          <feDropShadow flood-opacity="0.1" stdDeviation="10" dy="-4" dx="-2" filterUnits="userSpaceOnUse"></feDropShadow>
        </filter>
      </defs>
      <g style="filter: url(#f2);">
        <g style="filter: url(#f3);">
      <path d="M167.1,52.17S209.77-28.24,301.66,10.6c0,0,59.62,23.52,56.34,96.81,0,0,55.45,16.41,51.79,79.86,0,0-.3,61.95-67.65,67.28H220.75q-72.56,0-145.12,0C29.57,254.66-2.8,215,.19,170.31c0,0,7.74-70,81.58-68.37C81.77,101.94,101.46,42.87,167.1,52.17Z" style="filter: url(#f1);"></path>
        </g>
      </g>
    </svg>                            
  </div>
  <div>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 409.96 254.59">
      <defs>
        <filter filterUnits="userSpaceOnUse" id="f1">
          <feDropShadow filterUnits="userSpaceOnUse" dx="1.5" dy="0.8" stdDeviation="1"></feDropShadow>
        </filter>
        <filter filterUnits="userSpaceOnUse" id="f2">
          <feDropShadow filterUnits="userSpaceOnUse" dx="-2" dy="1.8" stdDeviation="1"></feDropShadow>
        </filter>
        <filter filterUnits="userSpaceOnUse" id="f3">
          <feDropShadow flood-opacity="0.1" stdDeviation="10" dy="-4" dx="-2" filterUnits="userSpaceOnUse"></feDropShadow>
        </filter>
      </defs>
      <g style="filter: url(#f2);">
        <g style="filter: url(#f3);">
      <path d="M167.1,52.17S209.77-28.24,301.66,10.6c0,0,59.62,23.52,56.34,96.81,0,0,55.45,16.41,51.79,79.86,0,0-.3,61.95-67.65,67.28H220.75q-72.56,0-145.12,0C29.57,254.66-2.8,215,.19,170.31c0,0,7.74-70,81.58-68.37C81.77,101.94,101.46,42.87,167.1,52.17Z" style="filter: url(#f1);"></path>
        </g>
      </g>
    </svg>                            
  </div>
</div>   

Ответ №1:

Тени переполнения не сохраняются во время переходов преобразования, поэтому вам нужно добавить поля/отступы в поле, чтобы убедиться, что они в порядке.

Кстати, вы можете сделать свой SVG намного более лаконичным

  • Вам не нужно повторно объявлять фильтры в каждом встроенном фрагменте SVG
  • Вам нужно только объявить свои фильтрующие элементы в самом элементе фильтра (не в каждом примитиве).
  • Вы можете использовать самозакрывающиеся теги для feDropshadow («/>»)
  • Вы можете избавиться от стиля и просто объявить атрибут фильтра напрямую.
 <div>
  <button id="scale">
    scale
  </button>
  <div>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 409.96 254.59">
      <defs>
        <filter id="f1" >
          <feDropShadow  dx="1.5" dy="0.8" stdDeviation="1"/>
        </filter>
        <filter  id="f2">
          <feDropShadow dx="-2" dy="1.8" stdDeviation="1"/>
        </filter>
        <filter   id="f3" >
          <feDropShadow stdDeviation="10" dy="-4" dx="-2"/>
        </filter>
      </defs>
      <g filter="url(#f2)">
        <g filter=" url(#f3)">
      <path d="M167.1,52.17S209.77-28.24,301.66,10.6c0,0,59.62,23.52,56.34,96.81,0,0,55.45,16.41,51.79,79.86,0,0-.3,61.95-67.65,67.28H220.75q-72.56,0-145.12,0C29.57,254.66-2.8,215,.19,170.31c0,0,7.74-70,81.58-68.37C81.77,101.94,101.46,42.87,167.1,52.17Z" filter= "url(#f1)"></path>
        </g>
      </g>
    </svg>                            
  </div>
  <div>
  
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 409.96 254.59">
      <g filter= "url(#f2)">
        <g filter= "url(#f3)">
      <path d="M167.1,52.17S209.77-28.24,301.66,10.6c0,0,59.62,23.52,56.34,96.81,0,0,55.45,16.41,51.79,79.86,0,0-.3,61.95-67.65,67.28H220.75q-72.56,0-145.12,0C29.57,254.66-2.8,215,.19,170.31c0,0,7.74-70,81.58-68.37C81.77,101.94,101.46,42.87,167.1,52.17Z" filter= "url(#f1)"></path>
        </g>
      </g>
    </svg>                            
  </div>
</div>   

Комментарии:

1. Спасибо за советы, я понял, что могу повторно использовать идентификаторы фильтров. Есть ли лучшая практика объявлять их где-то еще в html и повторно использовать их?