响应式设计:在SVG中居中文本

时间:2016-09-05 21:27:17

标签: html css svg

我想在SVG圆圈内垂直和水平居中一个字母,使其保持居中并与圆圈保持相同的比例。虽然我有下面的代码,但我也有more,如果您调整预览的大小,那么您可以看到该字母与圆圈不成比例。



<ul>
  <li class="circleIcon" id="{{ item.id }}">
    <svg viewBox="0 0 100 100">
      <circle cx="46" cy="46" r="45" stroke="black" stroke-width="1" fill="grey" />
    </svg>
    <div>I</div>
  </li>
</ul>
&#13;
{{1}}
&#13;
&#13;
&#13;

如何在不使用Javascript的情况下使文字与圆圈成比例?感谢。

4 个答案:

答案 0 :(得分:1)

您可以在SVG中水平居中文本,但在垂直方向上没有完美的方法。

有些人会建议使用<foreignObject>在SVG中嵌入一小段HTML。然后利用HTML的能力进行居中。但对于像你这样的简单SVG来说,这对IMO来说太过分了。

另一个建议是使用dominant-baseline CSS属性as seen here。但这依赖于浏览器对这些字体表的支持以及具有这些表的字体。

我首选的解决方案是use a dy with a value in em units。您需要做的就是为您正在使用的字体找到正确的em值。它可以适用于任何字体大小。

例如,Verdana的正确值约为0.36em。下面的演示。

&#13;
&#13;
li {
  list-style-type: none;
  position: relative;
}

li div {
  font-size: 60vw;
  position: absolute;
  text-align: center;
  top: 7vw;
  left: -3vw;
  width: 100%;
}
&#13;
<ul>
  <li class="circleIcon" id="{{ item.id }}">
    <svg viewBox="0 0 100 100">
      <circle cx="46" cy="46" r="45" stroke="black" stroke-width="1" fill="grey" />
      <text x="46" y="46" font-family="Verdana" font-size="80" dy="0.36em" text-anchor="middle">I</text>
    </svg>
  </li>
</ul>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

如果你不需要来使用svg,你可以通过使元素为圆形,并给它一个边框和一个背景颜色来做到这一点。

修改:注意您对边框动画的评论。 CSS动画不仅限于svg s - 我已在我的解决方案中添加了边框颜色动画(了解the basics of CSS animations at W3Schools,并获取more in-depth on MDN)。

请注意,此结果甚至不需要多个元素。运行此代码段并向下滚动以查看其仅使用<div>i</div>

ul {
  margin: 0;
  padding: 0;
}

li, div {
  width: 80vw;
  height: 80vw;
  margin: 0 auto;

  text-align: center;

  /* the circle */
  background: gray;
  border: 1vw solid black; /* I would usually just use a px weight, but I'm trying to make it look like your example */
  border-radius: 50%; /* makes it circular */
  
  /* the letter */
  font-size: 60vw;
  line-height: 80vw; /* making the line-height the same as the parent element's height centers the letter vertically */
  
  /* animate the borders */
  -webkit-animation: pulse 5s infinite ease-in 0s;
  animation: pulse 5s infinite ease-in 0s;
}

/* the animation */
@-webkit-keyframes pulse {
  0% { border-color: black }
  50% { border-color: red }
}
@keyframes pulse {
  0% { border-color: black }
  50% { border-color: red }
}
<ul>
  <li>I</li>
</ul>

<div>i</div>

答案 2 :(得分:0)

您可以在不使用svg的情况下执行此操作并利用Flexbox:

现在你的html看起来更干净了:

<ul>
    <li class="circleIcon" id="{{ item.id }}">
        <div>I</div>
    </li>
</ul>

这里有一些解释我做了什么的css:

li{
  position:relative;
  list-style:none;
}

li div {
  position: relative;
  /* We center vertically and horizontally using flexbox */
  display: flex;
  align-items:center;
  justify-content:center;
  /* until here */
  width: 100%;
  height:0;
  padding: 50% 0;
  border-radius: 50%;
  font-size:60vw;
  /* just styling the circle */
  border: 5px solid black;
  background:grey;
}

我为你添加了一个小提琴:https://jsfiddle.net/3frft2gd/2/

注意:如果您希望文字继续扩展,您可以使用媒体查询,它会起作用,希望它有所帮助。

答案 3 :(得分:0)

如果您在使用SVG的text属性方面没有任何问题,那么这可以帮助您解决问题。

&#13;
&#13;
li {
  list-style-type: none;
  position: relative;
}
li text {
  font-size: 4em;
  line-height: 1;
}
&#13;
<ul>
  <li class="circleIcon" id="{{ item.id }}">
    <svg viewBox="0 0 100 100">
      <circle cx="46" cy="46" r="45" stroke="black" stroke-width="1" fill="grey" />
      <text x="45" y="45" font-family="Verdana" font-size="60" fill="black" alignment-baseline="central" text-anchor="middle">I</text>
    </svg>
  </li>
</ul>
&#13;
&#13;
&#13;