6
头图
Welcome to my public account: Front-end detective

Recently I saw such a problem in a thinking: it is necessary to draw a diamond with an adaptive size, and there is also a border, which is generally very common in flowcharts, and the effect is as follows

image.png

If there is no border, CSS clip-path can also easily cut out a diamond, but the border is not very easy to handle (usually it is simulated by nesting one layer or projection, but the effect is not very good), here Introduce an SVG method that makes full use of the zoom feature to achieve such an effect

1. Where does SVG come from?

SVG usually does not require handwritten code (except for a few basic shapes), and can generally be generated by design software (SVG is designed for machines at the beginning of the design, which is very unfavorable for human reading). For example, I'm drawing here with Figma (one polygon will do), any size will do

image-20220309164603804

Then I got this SVG

<svg width="167" height="90" viewBox="0 0 167 90" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.10786 45L83.5 1.13597L164.892 45L83.5 88.864L2.10786 45Z" fill="#FFECC7" fill-opacity="0.6" stroke="#FFB200" stroke-width="2"/>
</svg>

The effect in the browser is as follows

image-20220309165349236

Second, the scaling characteristics of SVG

Now SVG has a default size, if you manually change the default size of SVG, as follows

image-20220309165838992

Is it somewhat similar to the effect of object-fit:contain ? If you want the whole pavement to be covered, what should you do with forced stretching? The scaling attribute of SVG preserveAspectRatio needs to be used here, which indicates the scaling rule when the actual size of SVG is inconsistent with the size of viewBox , which is somewhat similar to the combination of object-fit and object-position . There are many values here, the default value is xMidYMid , which means to force proportional scaling and center alignment.

If you are interested, you can refer to this article: Understanding SVG viewport, viewBox, preserveAspectRatio scaling , the case is very detailed

Here we do not need proportional scaling, we can directly set it to none

<svg preserveAspectRatio="none">
...
</svg>

The effect is as follows

image-20220309171034870

3. SVG stroke scaling

After setting the unequal scaling, there is actually a small problem with the stroke. Under different sizes, the thickness of the stroke is different, as follows

image-20220309174946444

Is there a way to make the stroke not scale with the SVG dimensions? Of course there are! There is an attribute vector-effect in SVG, which can control the stroke not to be scaled and always keep the default size. If you are interested, you can refer to this article CSS vector-effect and SVG stroke stroke scaling , here you only need to use path Just add the attribute vector-effect="non-scaling-stroke" , which means that the stroke does not follow the scaling, as follows

<svg preserveAspectRatio="none">
    <path vector-effect="non-scaling-stroke">...</path>
</svg>

image-20220309213841268

In this way, an adaptive size diamond is realized, and the stroke will not be scaled. The complete SVG code is as follows

<svg width="100%" height="100%" preserveAspectRatio="none" viewBox="0 0 167 90" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path vector-effect="non-scaling-stroke" d="M2.10786 45L83.5 1.13597L164.892 45L83.5 88.864L2.10786 45Z" fill="#FFECC7" fill-opacity="0.6" stroke="#FFB200" stroke-width="2"/>
</svg>

Fourth, SVG inline base64

Usually, such a graphic is more suitable as a background image (SVG code is not very beautiful on the page). Surprisingly, after converting the SVG to base64, the above features still exist. Here, the SVG online compression and merge tool by Mr. Zhang Xinxu is used, as follows

image-20220309214905398

After conversion, just use this base64 directly as the background

div{
  background: url('data:image/svg+xml;base64,PHN2ZyBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIiB2aWV3Qm94PSIwIDAgMTY3IDkwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIHZlY3Rvci1lZmZlY3Q9Im5vbi1zY2FsaW5nLXN0cm9rZSIgZD0iTTIuMTA4IDQ1TDgzLjUgMS4xMzYgMTY0Ljg5MiA0NSA4My41IDg4Ljg2NCAyLjEwOCA0NXoiIGZpbGw9IiNGRkVDQzciIGZpbGwtb3BhY2l0eT0iLjYiIHN0cm9rZT0iI0ZGQjIwMCIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9zdmc+')
}

In this way, an adaptive diamond background is obtained.

Kapture 2022-03-09 at 21.55.50

Of course, after converting to base64, the color cannot be modified in real time, and it needs to be replaced as a whole

The full code can be accessed at SVG diamond

Fifth, to summarize

From this example, we can see the natural advantages of SVG, especially the scaling characteristics of strokes. If you use CSS to draw, you will probably encounter a lot of trouble. Here is a summary of the implementation points:

  1. SVG is generally drawn and exported through design software, no handwriting is required
  2. SVG maintains the original scale by default, and the scaling rules can be modified through preserveAspectRatio
  3. The thickness of the SVG stroke will be scaled with the overall size by default, and the original size can be maintained through the vector-effect setting
  4. SVG still has the above characteristics after being converted to base64, and is more suitable for use as a background image

SVG has always been more advantageous in graphics drawing, especially for such geometric shapes, which are more flexible in scaling and adaptive. If CSS implementation is difficult, consider SVG. Finally, if you think it's good and helpful to you, please like, bookmark, and forward ❤❤❤

Welcome to my public account: Front-end detective

XboxYan
18.1k 声望14.1k 粉丝