html - Is it possible to position SVG Text elements like a normal block element without using positional attributes? - Stack Ove

I'm playing around with this tutorial on using an SVG text element to render a video clipped by th

I'm playing around with this tutorial on using an SVG text element to render a video clipped by the text.

And in it the author positions the text element like this within the clipPath:

      <svg height="100%" width="100%">
        <clipPath id="text-overlay" width="100%" height="100%">
          <text id="title" x="0" y="0" dy="1.0em">OCEAN</text>
        </clipPath>
      </svg>

I was curious whether it's possible to get the text to position itself by just using display: block on svg, clipPath, and text elements, but it does not look like that works.

Do we have to use something like x="0" y="0" dy="1.0em" to position the text element or is there another way to get it to render like a display: block element within the wrapper container?

Demo inlined below.

body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-image: url(.jpg);
  background-position: center center;
  background-repeat: no-repeat;
  font-family: sans-serif;
  color: white;
}
.wrapper {
  position: relative;
  width: 65%;
  height: 20%;
  margin: 2rem auto 0 auto;
}
video {
  width: 100%;
  height: 100%;
  background: rgba(0, 100, 0, 0.9);
}
svg {
  display: block;
  background: rgba(0, 0, 0, 0.1);
  position: absolute;
  top: 0;
}

.clipped-video {
  -webkit-clip-path: url(#text-overlay);
  clip-path: url(#text-overlay);
}

clipPath {
  display: block;
}
text {
  display: block;
  font-family: sans-serif;
  font-weight: 900;
  font-size: 18vw;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Home</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <!--
      Need a visual blank slate?
      Remove all code in `styles.css`!
    -->
    <link rel="stylesheet" href="styles.css" />
    <script type="module" src="script.js"></script>
  </head>
  <body>
    <div class="wrapper">
      <video class="clipped-video" muted loop autoplay>
        <source src=".mp4">
        </source>
      </video>
      <svg height="100%" width="100%">
        <clipPath id="text-overlay" width="100%" height="100%">
          <text id="title" x="0" y="0" dy="1.0em">OCEAN</text>
        </clipPath>
      </svg>
    </div>
</body>
</html>

I'm playing around with this tutorial on using an SVG text element to render a video clipped by the text.

And in it the author positions the text element like this within the clipPath:

      <svg height="100%" width="100%">
        <clipPath id="text-overlay" width="100%" height="100%">
          <text id="title" x="0" y="0" dy="1.0em">OCEAN</text>
        </clipPath>
      </svg>

I was curious whether it's possible to get the text to position itself by just using display: block on svg, clipPath, and text elements, but it does not look like that works.

Do we have to use something like x="0" y="0" dy="1.0em" to position the text element or is there another way to get it to render like a display: block element within the wrapper container?

Demo inlined below.

body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-image: url(https://design2seo/assets/blog/svg-clipping/home_intro_bg.jpg);
  background-position: center center;
  background-repeat: no-repeat;
  font-family: sans-serif;
  color: white;
}
.wrapper {
  position: relative;
  width: 65%;
  height: 20%;
  margin: 2rem auto 0 auto;
}
video {
  width: 100%;
  height: 100%;
  background: rgba(0, 100, 0, 0.9);
}
svg {
  display: block;
  background: rgba(0, 0, 0, 0.1);
  position: absolute;
  top: 0;
}

.clipped-video {
  -webkit-clip-path: url(#text-overlay);
  clip-path: url(#text-overlay);
}

clipPath {
  display: block;
}
text {
  display: block;
  font-family: sans-serif;
  font-weight: 900;
  font-size: 18vw;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Home</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <!--
      Need a visual blank slate?
      Remove all code in `styles.css`!
    -->
    <link rel="stylesheet" href="styles.css" />
    <script type="module" src="script.js"></script>
  </head>
  <body>
    <div class="wrapper">
      <video class="clipped-video" muted loop autoplay>
        <source src="https://design2seo/assets/blog/svg-clipping/video_waves3.mp4">
        </source>
      </video>
      <svg height="100%" width="100%">
        <clipPath id="text-overlay" width="100%" height="100%">
          <text id="title" x="0" y="0" dy="1.0em">OCEAN</text>
        </clipPath>
      </svg>
    </div>
</body>
</html>

Share asked Mar 4 at 6:13 OleOle 47.5k70 gold badges238 silver badges445 bronze badges 2
  • Nice image! If I understood your question correctly, it is impossible, because SVG layout has nothing to do with HTML layout, despite the fact that the elements can share common features and CSS properties. Why would you want SVG text elements to behave like HTML blocks (I can guess)? – Sergey A Kryukov Commented Mar 4 at 6:22
  • Indeed the image and the web design for the crustac site rocks!. I was hoping I could just style the text element like any other html element by setting display: block on it, because that would permit more freedom with respect to setting margins, padding, etc. – Ole Commented Mar 4 at 7:19
Add a comment  | 

2 Answers 2

Reset to default 0

There is no CSS or HTML text positioning magic in SVG.

There is SVG magic.

Text in SVG can be positioned with a <textPath> using a (invisible) <path> as guideline:

<svg viewBox="0 0 200 50" style="background:beige;height:150px">
    <path id="horizontal" pathLength="100" d="M0 25h200" stroke="blue" />
    <text dy="0">
        <textPath href="#horizontal" startOffset="50" text-anchor="middle" dominant-baseline="middle" fill="green">
            Middle aligned
        </textPath>
    </text>
</svg>

Or more esoteric with <animateMotion> and <mpath>:

<style>
  svg{ background:beige; width:90vw }
  text{ fill: green }
</style>
<svg viewBox="0 0 200 50">
  <path id="slope" fill="none" stroke="blue" d="m10,10c40,0,45,35,180,35"></path>
  <text>One
    <animateMotion dur="1s" fill="freeze" keyPoints="0;.1" keyTimes="0;1" calcMode="linear">
      <mpath href="#slope"></mpath>
    </animateMotion>
  </text>
  <text>Two
    <animateMotion dur="1s" fill="freeze" keyPoints="0;.4" keyTimes="0;1" calcMode="linear">
      <mpath href="#slope"></mpath>
    </animateMotion>
  </text>
  <text>Three
    <animateMotion dur="1s" fill="freeze" keyPoints="0;.75" keyTimes="0;1"calcMode="linear">
      <mpath href="#slope"></mpath>
    </animateMotion>
  </text>
</svg>

The CSS property display is a property applies to HTML only. As others have said, SVG does not have block text layout controls like HTML does. In general, you have to set the position and size yourself.

The only exception to this "no layout" statement is that you can use the text-anchor property to align your text to the left, right, or centre of your text position. So, for example, you could centre your "OCEAN" text so that it appears roughly where you want it even if the available "sans-serif" font the browser chooses varies wildly from what you expect.

For example:

<clipPath id="text-overlay" width="100%" height="100%">
    <text id="title" x="50%" y="0" dy="1.0em" text-anchor="middle">OCEAN</text>
</clipPath>

body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-image: url(https://design2seo/assets/blog/svg-clipping/home_intro_bg.jpg);
  background-position: center center;
  background-repeat: no-repeat;
  font-family: sans-serif;
  color: white;
}
.wrapper {
  position: relative;
  width: 65%;
  height: 20%;
  margin: 2rem auto 0 auto;
}
video {
  width: 100%;
  height: 100%;
  background: rgba(0, 100, 0, 0.9);
}
svg {
  display: block;
  background: rgba(0, 0, 0, 0.1);
  position: absolute;
  top: 0;
}

.clipped-video {
  -webkit-clip-path: url(#text-overlay);
  clip-path: url(#text-overlay);
}

clipPath {
  display: block;
}
text {
  display: block;
  font-family: sans-serif;
  font-weight: 900;
  font-size: 18vw;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Home</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <!--
      Need a visual blank slate?
      Remove all code in `styles.css`!
    -->
    <link rel="stylesheet" href="styles.css" />
    <script type="module" src="script.js"></script>
  </head>
  <body>
    <div class="wrapper">
      <video class="clipped-video" muted loop autoplay>
        <source src="https://design2seo/assets/blog/svg-clipping/video_waves3.mp4">
        </source>
      </video>
      <svg height="100%" width="100%">
        <clipPath id="text-overlay" width="100%" height="100%">
          <text id="title" x="50%" y="0" dy="1.0em" text-anchor="middle">OCEAN</text>
        </clipPath>
      </svg>
    </div>
</body>
</html>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745059537a4608880.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信