垂直居中部分svg内容

时间:2017-05-27 14:45:16

标签: javascript html css svg center

我一直试图在CSS / JS中垂直居中一组svg路径/文本很长一段时间没有运气。到目前为止,我在这里找到的解决方案都没有奏效。我有多个<文字> ,< circle>,< rect>,虽然我不认为内容的类型真的很重要。

高度是可变的,所以我想到了两种方法: 1)通过50%转换。这是行不通的,因为你无法从svg转换内容的子集,这是我迄今为止所发现的。 < g>标签很有希望,但我没有运气。

2)我的第二个想法是在加载内容后通过javascript调整掩码。同样,这也不起作用。

所有代码都在代码笔上并在此处复制:https://codepen.io/anon/pen/MmdWXB

HTML:

<div class="mask_group" id="mask_container">
<div class="text">
  <svg>
   <defs>
     <mask id="mask" x="0" y="0" width="100%" height="100%" >
       <rect class="cutout label" x="0" y="0" width="100%" height="100%"/>
       <text class="label normal_font_weight" y="1em" dy="0em" x="50%">A</text>
       <text class="label normal_font_weight" y="3em" dy="0em" x="50%">B</text>
       <line class="label" x1="47%" y1="4.6em" x2="53%" y2="4.6em" style="stroke:rgb(255,0,0);stroke-width:1.5" />
       <text class="label" y="7em" dy="0em" x="50%">C</text>
       <text class="label" y="9em" id="final_text" dy="0em" x="50%">D</text>
        </mask>
    </defs>
    <rect id="base" x="0" y="0" width="100%" height="100%"/>
  </svg>
</div>
</div>

<div style="background-color:blue; width: 100%; height: 100%">
</div>

CSS:

html,body {
height: 100%;
}

.text {
  position: relative;
   /*top: 0;
   left: 0;*/
   width: 100%;
   height: 100%;
   margin-left: 0%;
   /*z-index: 11; */
 }

 .mask_group {
   position: fixed;
   width: 100%;
   height: 100%;
   z-index: 10; 

 }

 svg {
   position: absolute;
   width: 100%;
   height: inherit;
 }
 svg text {
   text-anchor: middle;
 }
 .cutout {
   fill: white;
 }

 svg #base {
   fill: #051E2A; /*#1F5773;*/
   -webkit-mask: url(#mask);
           mask: url(#mask);
 }


 /*Unused*/
 .vert_center {
   position: relative;
   margin-top: 50%;
   transform: translateY(-50%);

 }

JS:

function body_loaded() {

  var final_text = document.getElementById("final_text");
  var position = final_text.getBoundingClientRect();
  var bottom = position.bottom;

  var mask_container = document.getElementById("mask_container");
  var mask_position = mask_container.getBoundingClientRect();
  var mask_height = mask_position.height;

  var origin_y = (mask_height - bottom) / 2;
  alert(origin_y);

  var mask = document.getElementById("mask"); 
  mask.style.y = origin_y;
}

提前致谢!

1 个答案:

答案 0 :(得分:1)

我不确定你试图用<mask>做什么,所以我暂时忽略它。

要使SVG垂直居中,只需给它一个固定的高度并使用标准的translate(-50%)技巧。唯一的缺点是您无法将CSS transform放在<svg>元素上,因为transform在SVG中的行为与在CSS中的行为不同。 SVG转换了早期的CSS转换。因此,您只需将SVG包装在HTML容器中,然后将transform应用于该容器。

我已将<svg>的高度设置为10em。如果你有更多的文字,显然你需要调整它。你可以用JS使用

做到这一点
svgElem.setAttribute("height", "10em");

但首先明确地将它从CSS中删除:)

html,body {
height: 100%;
}

.svg-wrapper {
  position: absolute;
  width: 100%;
  top: 50%;
  transform: translate(0, -50%);
}

.mask_group {
  position: fixed;
  width: 100%;
  height: 100%;
  z-index: 10; 
}

svg {
  width: 100%;
  height: 10em;
  fill: blue;  /* default fill colour for contents */
}
svg text {
  text-anchor: middle;
}

svg #base {
  fill: #051E2A; /*#1F5773;*/
}
<div class="mask_group" id="mask_container">
  <div class="svg-wrapper">
    <svg>
      <rect id="base" x="0" y="0" width="100%" height="100%"/>
      <text class="label normal_font_weight" y="1em" dy="0em" x="50%">A</text>
      <text class="label normal_font_weight" y="3em" dy="0em" x="50%">B</text>
      <line class="label" x1="47%" y1="4.6em" x2="53%" y2="4.6em" style="stroke:rgb(255,0,0);stroke-width:1.5" />
      <text class="label" y="7em" dy="0em" x="50%">C</text>
      <text class="label" y="9em" id="final_text" dy="0em" x="50%">D</text>
    </svg>
  </div>
</div>

<div style="background-color:blue; width: 100%; height: 100%">
</div>