Вертикальное позиционирование SVG-элемента поверх и под другие элементы

95
14 февраля 2021, 07:50

Нужно, чтобы элемент rect1 был расположен под rect2, но rect3 (синий) располагался над rect2 (зелёный) и под rect1 (красный).

Как можно сделать такое позиционирование?

Далее, мой пример с ошибкой, где rect3 располагается под rect2:

<svg width="350" height="300"> 
  <rect id="rect3" width="100" height="50" x="75" y="0" fill="blue"/> 
  <rect id="rect1" width="100" height="75" x="0" y="0" fill="red"/> 
  <rect id="rect2" width="80" height="50" x="0" y="0" fill="green"/> 
</svg>

Answer 1

SVG позиционирование

Как уже отметили в комментариях z-index в svg не поможет. Так как его нет там по определению. Взаимное расположение элементов сродни абсолютному позиционированию: какая строчка кода, определяющая элемент SVG написана последней, тот элемент и будет самым верхним.
То есть в вашем случае разноцветные квадраты будут расположены друг над другом в порядке их написания в коде SVG.

В примере ниже, чтобы это было чётко видно, я задал разные размеры квадратам и одинаковые координаты левого, верхнего угла прямоугольников, совпадающими с началом координат SVG полотна. x="0" y="0"

<svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="300" height="300" viewBox="0 0 300 300" >    
 <rect id="rect1" x="0" y="0" width="200" height="200"  fill="red"/> 
 <rect id="rect2" x="0" y="0" width="150" height="150"  fill="blue"/> 
 <rect id="rect3" x="0" y="0" width="100" height="100"   fill="green"/> 
</svg>

CSS позиционирование

Если всё таки хочется применить z-index для вертикального позиционирования элементов SVG, то необходимо каждый элемент SVG обернуть div-ами, задать им pozition:absolute; и тогда с помощью z-index можно регулировать вертикальное расположение прямоугольников.

В примере ниже z-index:1; у всех блоков одинаковый, поэтому они располагаются в порядке следования, как в коде

 .wrap { 
  position:absolute; 
  } 
 .red { 
  position:absolute; 
 top:0; 
  
 z-index:1; 
 } 
 .blue { 
 position:absolute; 
 top:0; 
 z-index:1; 
 } 
 .green { 
 position:absolute; 
 top:0; 
 z-index:1; 
 }
<div class="wrap"> 
<div class="red"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="300" height="300" viewBox="0 0 300 300" >    
    <rect id="rect1" x="0" y="0" width="300" height="300"  fill="red" /> 
  </svg> 
</div> 
 
<div class="blue"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="200" height="200" viewBox="0 0 200 200" >    
 <rect id="rect2" x="0" y="0" width="200" height="200"  fill="blue"/> 
 </svg> 
</div>  
 
<div class="green"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="150" height="150" viewBox="0 0 150 150" >    
 <rect id="rect2" x="0" y="0" width="150" height="150"  fill="green" /> 
 </svg> 
</div> 
 
</div>

Присваиваем синему квадрату бОльший -z-index:2; и он перекроет зелёный квадрат:

.wrap { 
  position:absolute; 
  } 
 .red { 
  position:absolute; 
 top:0; 
  
 z-index:1; 
 } 
 .blue { 
 position:absolute; 
 top:0; 
 z-index:2; 
 } 
 .green { 
 position:absolute; 
 top:0; 
 z-index:1; 
 }
<div class="wrap"> 
<div class="red"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="300" height="300" viewBox="0 0 300 300" >    
    <rect id="rect1" x="0" y="0" width="300" height="300"  fill="red" /> 
  </svg> 
</div> 
 
<div class="blue"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="200" height="200" viewBox="0 0 200 200" >    
 <rect id="rect2" x="0" y="0" width="200" height="200"  fill="blue"/> 
 </svg> 
</div>  
 
<div class="green"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="150" height="150" viewBox="0 0 150 150" >    
 <rect id="rect2" x="0" y="0" width="150" height="150"  fill="green" /> 
 </svg> 
</div> 
 
</div>

JS позиционирование

При наведении курсора на прямоугольник он становится верхним

var svg = document.querySelector("svg"); 
var rects = document.querySelectorAll("rect"); 
 
var i = rects.length; 
while(i--) { 
  rects[i].addEventListener("mouseenter", function(e) { 
    svg.appendChild(e.target); 
  }); 
}
body {  
  background-color: #170A1E;  
  margin: 20px; 
  color: gold; 
  font-size:18px; 
} 
 
svg { 
  width: 400px; 
  height: 400px; 
}
<p>Наведение курсора меняет вертикальное расположение квадратов</p> 
<svg> 
  <rect x="0" y="0" width="200" height="200" fill="dodgerblue" stroke="black"></rect> 
  <rect x="125" y="50" width="200" height="200" fill="red" stroke="black"></rect> 
  <rect x="50" y="125" width="200" height="200" fill="yellowgreen" stroke="black"></rect> 
</svg> 

Answer 2

Красный под синим, синий под зелёным, зелёный под красным:

<svg width="350" height="100"> 
  <rect id="r-red" width="100" height="75" x="0" y="0" fill="red" /> 
  <rect id="r-blue" width="100" height="50" x="75" y="0" fill="blue" /> 
  <rect id="r-green" width="80" height="50" x="0" y="0" fill="green" clip-path="url(#c-blue)" /> 
   
  <defs> 
    <clipPath id="c-blue"> 
      <use xlink:href="#r-blue" /> 
    </clipPath> 
  </defs> 
</svg>

READ ALSO
WPF Как привязать стиль из Windows10?

WPF Как привязать стиль из Windows10?

Только вчера сел изучать WPF, так что прошу не кидаться "камнями в мой огород"

99
Фоновые задачи в Xamarin

Фоновые задачи в Xamarin

Попытался реализовать работу фоновой задачи в Android и iOS как это описано в статье

110
Uri типа &ldquo;pack&rdquo; в Wpf

Uri типа “pack” в Wpf

У меня есть консольное приложение с подключённой сборкой PresentationCore(тесты делаются здесь - так проще; проверял в оконном приложении и результаты...

109