我应该使用CSS还是SVG来显示形状?

12

我一直在使用CSS在我的网站上尝试不同的形状,但有时候修改它们会很麻烦,例如三角形实际上是一个带有边框的矩形。

我正在使用CSS-tricks article作为CSS创建形状的指南。

我想使用CSS,因为它比使用图像加载更快。

几天过去了,我偶然发现了SVG。我一直看到它们在网上出现,但从未深入研究过。所以我想知道,使用SVG相对于这些CSS“技巧”来实现我的形状是否更简单。找不到与此特定主题相关的可靠信息,因此欢迎提供任何关于SVG的信息。(这些形状将超过1000像素宽,因此我不想使用图像...)

简而言之:想要在网页上拥有形状时,跨浏览器/加载时间方面,哪个更好?我刚刚了解了SVG并想知道它是否是一个可行的选项。


编辑

抱歉,以下是我目前用于实现效果的代码,以及我想要实现的效果的图像(不幸的是,设计该图像的人没有提供设计的代码,只有图像)。

源图像

Image of design hoping to achieve

我的代码 (如果你不喜欢SASS,抱歉)

<div class="arrow-wrap">
  <div class="arrow">
    <div class="arrow-text">
      <h1>Services</h1>
      <p>Learn more about our services by selecting one below</p>
    </div>
  </div>
</div>

.arrow-wrap
    overflow: hidden;
    display: flex
    justify-content: center
    position: relative
    z-index: 10
    .arrow
        width: 0
        height: 0
        border-style: solid
        border-width: 150px 100vw 0 100vw
        border-color: $dark transparent transparent transparent
        position: relative
        z-index: 1
        display: flex
        justify-content: center
        .arrow-text
            text-align: center
            margin-top: -130px
            white-space: nowrap
            position: relative
            z-index: 5
            h1
                font-size: 50px
                margin: 0
            p
                margin: 0
                color: rgba($white, 0.8)

我的成果图 我的设计原型的图片

所以,由于我必须费力地让文本工作 (缩放仍不完美),我想知道是否采用SVG的方式更有效,即如果SVG在完成工作/加载时间方面更有效。


编辑2

我也在思考 - 为了在顶部增加更多空间 - 添加一个实心盒子阴影,以营造它是一个不规则五边形的幻象 (在YouTube上找到这里)

输入图像描述


SVG 可以让你创建任何复杂度的形状,它是一种矢量图像格式,而不是样式描述。CSS 只能通过技巧来创建简单的形状(实际上并不是真正的形状,只是将 HTML 元素样式化成某些形状)。因此,如果你只需要简单的形状,使用 CSS;如果你需要复杂的形状,使用 SVG。 - Gusman
2个回答

8

同时使用。

CSS

对于基本形状和简单动画,使用CSS。 正如您所提到的,当您使用CSS生成自定义形状时,您所做的就是添加边框或盒子阴影来创建所需的形状的幻象。有人可能会说这并不是未来可靠的方法,因为它可能在任何更新中出现问题。

SVG

对于更复杂的形状和动画,使用SVG。 根据您实现SVG的方式,您可以做一些事情。您可以直接嵌入它们或通过HTML img标签嵌入它们,甚至可以使用JavaScript库将它们注入应用程序中。

SVG可以通过操作svg本身的样式进行动画,但这(取决于您的目标)可能会变得非常复杂。我的建议是使用JavaScript库进行SVG动画。

我的建议是两者都使用。先了解CSS的使用。对我而言,如果您想快速完成任务,似乎这是最容易掌握的路线。也尝试使用SVG。我曾经使用SVG库创建过一些很棒的效果,这些效果仅使用CSS是无法实现的,它们甚至在IE9中也可以运行(尽管它已经不再受支持)。

简而言之:

对于基本形状和动画,请使用CSS

对于高级形状和动画,请使用SVG。


我想补充一下,使用CSS制作的动画由浏览器的另一个线程处理,因此它们不会因CPU负载而减慢速度,而SVG则会。 - Alessandro_Russo
1
@Alessandro_russo 你应该看一下Web Workers,使用它们可能会实现这个功能 https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Using_web_workers - Daniel Tate

4

回答原始问题:

如果你考虑从http服务器传输数据到连接客户端的时间,并且形状是简单的绘图,不包含自定义曲率或路径或多个层,则CSS在显示形状方面要快得多。

SVG主要是动画和复杂艺术品的工具。

基本上有两种方法可以呈现更复杂的动画和绘图(我的意思是像网页上的俄罗斯方块游戏之类的)

您可以使用SVG或CANVAS。 (还有其他第三方插件,如Shockwave / Flash等)

但基本上,Canvas是使用SVG的更易于使用的替代方法,因为它很友好地支持JavaScript。您可以使用JavaScript动态绘制Canvas。

您也可以使用JavaScript在SVG内联元素上绘制,但如果没有额外的JavaScript库(例如SVG.JS或SNAP.JS),这并不简单。

另一方面,与Canvas相比,SVG更容易缩放到不同的大小。您只需更改SVG元素的视口即可实现已缩放的图像。HTML5画布可能更难以缩放到正确的大小。

CSS具有更轻量级和更快速加载的优点,但在进行复杂的多层动画和其他事情(例如图层蒙版/着色器效果)方面要困难得多,因为您必须手动计算所有简单的几何图形,而不是让计算机来做。

因此,选择使用SVG、CSS和HTML5 CANVAS来呈现您的图像完全取决于您。大多数良好的网页都结合了这三种方法,因为它们在不同方面都有所优势。

我附上了一个示例,介绍如何使用您提供的代码以及HTML5 Canvas来动态创建形状。

.arrow-wrap: {
  overflow: hidden;
  display: flex justify-content: center position: relative z-index: 10
}
.arrow: {
  width: 0 height: 0 border-style: solid border-width: 150px 100vw 0 100vw border-color: $dark transparent transparent transparent position: relative z-index: 1 display: flex justify-content: center
}
.arrow-text: {
  text-align: center margin-top: -130px white-space: nowrap position: relative z-index: 5
}
h1: {
  font-size: 50px margin: 0
}
p: {
  margin: 0 color: rgba($white, 0.8)
}
</style
<!DOCTYPE HTML>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">


</head>

<body>
  <div class="arrow-wrap">
    <div>
      <div class="arrow-text">
        <h1 class="arrow">Services</h1>



        <p>Learn more about our services by selecting one below</p>
      </div>

    </div>
    <div class="arrow"><a href="#">My Service 1</a>
    </div>
    <div class="arrow"><a href="#">Service 2</a>
    </div>

  </div>
</body>

<script>
  var canv_active_id = 0;
  // find al elements of arrow class
  var x = document.getElementsByClassName("arrow");
  var i;
  for (i = 0; i < x.length; i++) {
    // create a canvas element with uniqueID
    var canv = document.createElement('canvas');
    canv.id = "canvas" + canv_active_id;
    canv.width = 21;
    canv.height = 24;
    canv.style.width = x[i].innerWidth * 0.05;
    canv.style.height = x[i].innerHeight * 0.55;

    //place the canvas element at the start of 
    //element
    var old_html = x[i].innerHTML;
    x[i].innerHTML = "";

    x[i].appendChild(canv);

    x[i].innerHTML += old_html;

    // get canvas context
    var ctx = document.getElementById("canvas" + canv_active_id).getContext('2d');
    // setup viewport
    ctx.scale(canv.style.width, x[i].innerHeight);

    ctx.save();
    ctx.transform(1.000000, 0.000000, 0.000000, 1.000000, -126.526770, -266.500710);


    // perform drawing by using lineTo()
    // #path4138
    ctx.beginPath();
    ctx.globalAlpha = 0.7;
    ctx.miterLimit = 8.19999981;
    ctx.lineWidth = 1.000000;
    ctx.fillStyle = 'rgba(215, 238, 244, 0.7)';
    ctx.moveTo(126.526770, 266.500710);
    ctx.lineTo(137.339480, 271.799980);
    ctx.lineTo(148.152170, 277.099260);
    ctx.lineTo(137.408870, 284.043060);
    ctx.lineTo(126.665560, 290.986860);
    ctx.lineTo(126.596160, 278.743780);
    ctx.fill();
    ctx.restore();

    //increase unique ID
    canv_active_id++;
  }
</script>



</html>

如果你需要大量的形状,那么使用CANVAS可能是一个不错的选择,但也可能不是。你需要根据页面内容来做出决定。


为您添加了更多内容供您查看。到目前为止提供的信息非常有帮助,谢谢。 - sparcut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接