Archive

Archive for September, 2024

SVG Coding Examples: Useful Recipes For Writing Vectors By Hand

September 18th, 2024 No comments

Even though I am the kind of front-end engineer who manually cleans up SVG files when they are a mess, I never expected to become one of those people. You know, those crazy people that draw with code.

But here we are.

I dove deep into SVG specs last winter when I created a project to draw Calligraphy Grids, and even though I knew the basic structures and rules of SVG, it was only then that I fully tried to figure out and understand what all of those numbers meant and how they interacted with each other.

And, once you get the hang of it, it is actually very interesting and quite fun to code SVG by hand.

No ahead

We won’t go into more complex SVG shapes like paths in this article, this is more about practical information for simple SVGs. When it comes to drawing curves, I still recommend using a tool like Illustrator or Affinity. However, if you are super into compounding your lines, a path is useful. Maybe we’ll do that in Part 2.

Also, this guide focuses mostly on practical examples that illustrate some of the math involved when drawing SVGs. There is a wonderful article here that goes a bit deeper into the specs, which I recommend reading if you’re more interested in that: “A Practical Guide To SVG And Design Tools.”

Drawing With Math. Remember Coordinate Systems?

Illustrator, Affinity, and all other vector programs are basically just helping you draw on a coordinate system, and then those paths and shapes are stored in SVG files.

If you open up these files in an editor, you’ll see that they are just a bunch of paths that contain lots of numbers, which are coordinates in that coordinate system that make up the lines.

But, there is a difference between the all-powerful and the other, more semantic elements like , , , , , and .

These elements are not that hard to read and write by hand, and they open up a lot of possibilities to add animation and other fun stuff. So, while most people might only think of SVGs as never-pixelated, infinitely scaling images, they can also be quite comprehensive pieces of code.

How Does SVG Work? unit != unit

Before we get started on how SVG elements are drawn, let’s talk about the ways units work in SVG because they might be a bit confusing when you first get started.

The beauty of SVG is that it’s a vector format, which means that the units are somewhat detached from the browser and are instead just relative to the coordinate system you’re working in.

That means you would not use a unit within SVG but rather just use numbers and then define the size of the document you’re working with.

So, your width and height might be using CSS rem units, but in your viewBox, units become just a concept that helps you in establishing sizing relationships.

What Is The viewBox?

The viewBox works a little bit like the CSS aspect-ratio property. It helps you establish a relationship between the width and the height of your coordinate system and sets up the box you’re working in. I tend to think of the viewBox as my “document” size.

Any element that is placed within the SVG with bigger dimensions than the viewBox will not be visible. So, the viewBox is the cutout of the coordinate system we’re looking through. The width and height attributes are unnecessary if there is a viewBox attribute.

So, in short, having an SVG with a viewBox makes it behave a lot like a regular image. And just like with images, it’s usually easiest to just set either a width or a height and let the other dimension be automatically sized based on the intrinsic aspect ratio dimensions.

So, if we were to create a function that draws an SVG, we might store three separate variables and fill them in like this:

`<svg 
  width="${svgWidth}" 
  viewBox="0 0 ${documentWidth} ${documentHeight}" 
  xmlns="http://www.w3.org/2000/svg"
>`;

SVG Things Of Note

There is a lot to know about SVG: When you want to reuse an image a lot, you may want to turn it into a symbol that can then be referenced with a use tag, you can create sprites, and there are some best practices when using them for icons, and so on.

Unfortunately, this is a bit out of the scope of this article. Here, we’re mainly focusing on designing SVG files and not on how we can optimize and use them.

However, one thing of note that is easier to implement from the start is accessibility.

SVGs can be used in an tag, where alt tags are available, but then you lose the ability to interact with your SVG code, so inlining might be your preference.

When inlining, it’s easiest to declare role="img" and then add a </code> tag with your image title.</p> <p><strong>Note</strong>: <em>You can check out <a target="_blank" href="https://www.smashingmagazine.com/2021/05/accessible-svg-patterns-comparison/" rel="noopener">this article for SVG and Accessibility recommendations</a>.</em></p> <pre><code><svg role="img" [...attr] > <title>An accessible title</title> <!-- design code --> </svg> </code></pre> <p>Drawing SVG With JavaScript</p> <p>There is usually some mathematics involved when drawing SVGs. It’s usually fairly simple arithmetic (except, you know, in case you draw calligraphy grids and then have to dig out trigonometry…), but I think even for simple math, most people don’t write their SVGs in pure HTML and thus would like to use algebra.</p> <p>At least for me, I find it much easier to understand SVG Code when giving meaning to numbers, so I always stick to JavaScript, and by giving my coordinates names, I like them immeasurable times more.</p> <p>So, for the upcoming examples, we’ll look at the list of variables with the simple math and then JSX-style templates for interpolation, as that gives more legible syntax highlighting than string interpolations, and then each example will be available as a CodePen.</p> <p>To keep this Guide framework-agnostic, I wanted to quickly go over drawing SVG elements with just good old vanilla JavaScript.</p> <p>We’ll create a container element in HTML that we can put our SVG into and grab that element with JavaScript.</p> <pre><code><div data-svg-container></div> <script src="template.js"></script> </code></pre> <p>To make it simple, we’ll draw a rectangle <code></code> that covers the entire <code>viewBox</code> and uses a fill.</p> <p><strong>Note</strong>: <em>You can add all valid CSS values as fills, so a fixed color, or something like <code>currentColor</code> to access the site’s text color or a CSS variable would work here if you’re inlining your SVG and want it to interact with the page it’s placed in.</em></p> <p>Let’s first start with our variable setup.</p> <div> <pre><code>// vars const container = document.querySelector("[data-svg-container]"); const svgWidth = "30rem"; // use any value with units here const documentWidth = 100; const documentHeight = 100; const rectWidth = documentWidth; const rectHeight = documentHeight; const rectFill = "currentColor"; // use any color value here const title = "A simple square box"; </code></pre> </div> <h3>Method 1: Create Element and Set Attributes</h3> <p>This method is easier to keep type-safe (if using TypeScript) — uses proper SVG elements and attributes, and so on — but it is less performant and may take a long time if you have many elements.</p> <div> <pre><code>const svg = document.createElementNS("<a target="_blank" href="http://www.w3.org/2000/svg%22" rel="noopener">http://www.w3.org/2000/svg"</a>, "svg"); const titleElement = document.createElementNS("<a target="_blank" href="http://www.w3.org/2000/svg%22" rel="noopener">http://www.w3.org/2000/svg"</a>, "title"); const rect = document.createElementNS("<a target="_blank" href="http://www.w3.org/2000/svg%22" rel="noopener">http://www.w3.org/2000/svg"</a>, "rect"); svg.setAttribute("width", svgWidth); svg.setAttribute("viewBox", <code>0 0 ${documentWidth} ${documentHeight}</code>); svg.setAttribute("xmlns", "<a target="_blank" href="http://www.w3.org/2000/svg%22)" rel="noopener">http://www.w3.org/2000/svg")</a>; svg.setAttribute("role", "img"); titleElement.textContent = title; rect.setAttribute("width", rectWidth); rect.setAttribute("height", rectHeight); rect.setAttribute("fill", rectFill); svg.appendChild(titleElement); svg.appendChild(rect); container.appendChild(svg); </code></pre> </div> <p><img decoding="async" src="https://files.smashing.media/articles/svg-coding-examples-recipes-writing-vectors-by-hand/polygon-polyline-composite-fixed.png"></p> <p>Here, you can see that with the same coordinates, a polyline won’t draw the line between the blue and the red dot, while a polygon will. However, when applying a fill, they take the exact same information as if the shape was closed, which is the right side of the graphic, where the polyline makes it look like a piece of a circle is missing.</p> <p>This is the second time where we have dealt with quite a bit of repetition, and we can have a look at how we could leverage the power of JavaScript logic to render our template faster.</p> <p>But first, we need a basic implementation like we’ve done before. We’re creating objects for the circles, and then we’re chaining the <code>cx</code> and <code>cy</code> values together to create the <code>points</code> attribute. We’re also storing our transforms in variables.</p> <div> <pre><code>const polyDocWidth = 200; const polyDocHeight = 200; const circleOne = { cx: 25, cy: 80, r: 10, fill: "red" }; const circleTwo = { cx: 40, cy: 20, r: 5, fill: "lime" }; const circleThree = { cx: 70, cy: 60, r: 8, fill: "cyan" }; const points = <code>${circleOne.cx},${circleOne.cy} ${circleTwo.cx},${circleTwo.cy} ${circleThree.cx},${circleThree.cy}</code>; const moveToTopRight = <code>translate(${polyDocWidth / 2}, 0)</code>; const moveToBottomRight = <code>translate(${polyDocWidth / 2}, ${polyDocHeight / 2})</code>; const moveToBottomLeft = <code>translate(0, ${polyDocHeight / 2})</code>; </code></pre> </div> <p>And then, we apply the variables to the template, using either a <code>polyline</code> or <code>polygon</code> element and a <code>fill</code> attribute that is either set to <code>none</code> or a color value.</p> <pre><code> <svg width={svgWidth} viewBox={`0 0 ${polyDocWidth} ${polyDocHeight}`} xmlns="http://www.w3.org/2000/svg" role="img" > <title>Composite shape comparison</title> <g> <circle cx={circleOne.cx} cy={circleOne.cy} r={circleOne.r} fill={circleOne.fill} /> <circle cx={circleTwo.cx} cy={circleTwo.cy} r={circleTwo.r} fill={circleTwo.fill} /> <circle cx={circleThree.cx} cy={circleThree.cy} r={circleThree.r} fill={circleThree.fill} /> <polyline points={points} fill="none" stroke="black" /> </g> <g transform={moveToTopRight}> <circle cx={circleOne.cx} cy={circleOne.cy} r={circleOne.r} fill={circleOne.fill} /> <circle cx={circleTwo.cx} cy={circleTwo.cy} r={circleTwo.r} fill={circleTwo.fill} /> <circle cx={circleThree.cx} cy={circleThree.cy} r={circleThree.r} fill={circleThree.fill} /> <polyline points={points} fill="white" stroke="black" /> </g> <g transform={moveToBottomLeft}> <circle cx={circleOne.cx} cy={circleOne.cy} r={circleOne.r} fill={circleOne.fill} /> <circle cx={circleTwo.cx} cy={circleTwo.cy} r={circleTwo.r} fill={circleTwo.fill} /> <circle cx={circleThree.cx} cy={circleThree.cy} r={circleThree.r} fill={circleThree.fill} /> <polygon points={points} fill="none" stroke="black" /> </g> <g transform={moveToBottomRight}> <circle cx={circleOne.cx} cy={circleOne.cy} r={circleOne.r} fill={circleOne.fill} /> <circle cx={circleTwo.cx} cy={circleTwo.cy} r={circleTwo.r} fill={circleTwo.fill} /> <circle cx={circleThree.cx} cy={circleThree.cy} r={circleThree.r} fill={circleThree.fill} /> <polygon points={points} fill="white" stroke="black" /> </g> </svg> </code></pre> <p>And here’s a version of it to play with:</p> <p>See the Pen <a target="_blank" href="https://codepen.io/smashingmag/pen/OJeeVoM" rel="noopener">SVG Polygon / Polyline (simple) [forked]</a> by <a target="_blank" href="https://codepen.io/mynimi" rel="noopener">Myriam</a>.</p> <p>Dealing With Repetition</p> <p>When it comes to drawing SVGs, you may find that you’ll be repeating a lot of the same code over and over again. This is where JavaScript can come in handy, so let’s look at the composite example again and see how we could optimize it so that there is less repetition.</p> <p><strong>Observations:</strong></p> <ul> <li>We have three circle elements, all following the same pattern.</li> <li>We create one repetition to change the <code>fill</code> style for the element.</li> <li>We repeat those two elements one more time, with either a <code>polyline</code> or a <code>polygon</code>.</li> <li>We have four different <code>transforms</code> (technically, no transform is a transform in this case).</li> </ul> <p>This tells us that we can create nested loops.</p> <p>Let’s go back to just a vanilla implementation for this since the way loops are done is quite different across frameworks.</p> <p>You could make this more generic and write separate generator functions for each type of element, but this is just to give you an idea of what you could do in terms of logic. There are certainly still ways to optimize this.</p> <p>I’ve opted to have arrays for each type of variation that we have and wrote a helper function that goes through the data and builds out an array of objects with all the necessary information for each group. In such a short array, it would certainly be a viable option to just have the data stored in one element, where the values are repeated, but we’re taking the DRY thing seriously in this one.</p> <p>The group array can then be looped over to build our SVG HTML.</p> <div> <pre><code>const container = document.querySelector("[data-svg-container]"); const svgWidth = 200; const documentWidth = 200; const documentHeight = 200; const halfWidth = documentWidth / 2; const halfHeight = documentHeight / 2; const circles = [ { cx: 25, cy: 80, r: 10, fill: "red" }, { cx: 40, cy: 20, r: 5, fill: "lime" }, { cx: 70, cy: 60, r: 8, fill: "cyan" }, ]; const points = circles.map(({ cx, cy }) => <code>${cx},${cy}</code>).join(" "); const elements = ["polyline", "polygon"]; const fillOptions = ["none", "white"]; const transforms = [ undefined, <code>translate(${halfWidth}, 0)</code>, <code>translate(0, ${halfHeight})</code>, <code>translate(${halfWidth}, ${halfHeight})</code>, ]; const makeGroupsDataObject = () => { let counter = 0; const g = []; elements.forEach((element) => { fillOptions.forEach((fill) => { const transform = transforms[counter++]; g.push({ element, fill, transform }); }); }); return g; }; const groups = makeGroupsDataObject(); // result: // [ // { // element: "polyline", // fill: "none", // }, // { // element: "polyline", // fill: "white", // transform: "translate(100, 0)", // }, // { // element: "polygon", // fill: "none", // transform: "translate(0, 100)", // }, // { // element: "polygon", // fill: "white", // transform: "translate(100, 100)", // } // ] const svg = document.createElementNS("<a target="_blank" href="http://www.w3.org/2000/svg%22" rel="noopener">http://www.w3.org/2000/svg"</a>, "svg"); svg.setAttribute("width", svgWidth); svg.setAttribute("viewBox", <code>0 0 ${documentWidth} ${documentHeight}</code>); svg.setAttribute("xmlns", "<a target="_blank" href="http://www.w3.org/2000/svg%22)" rel="noopener">http://www.w3.org/2000/svg")</a>; svg.setAttribute("role", "img"); svg.innerHTML = "<title>Composite shape comparison</title>"; groups.forEach((groupData) => { const circlesHTML = circles .map((circle) => { return <code>&lt;circle cx="${circle.cx}" cy="${circle.cy}" r="${circle.r}" fill="${circle.fill}" /&gt;</code>; }) .join(""); const polyElementHTML = <code>&lt;${groupData.element} points="${points}" fill="${groupData.fill}" stroke="black" /&gt;</code>; const group = <code>&lt;g ${groupData.transform ?</code>transform="${groupData.transform}"<code>: ""}&gt; ${circlesHTML} ${polyElementHTML} &lt;/g&gt;</code>; svg.innerHTML += group; }); container.appendChild(svg); </code></pre> </div> <p>And here’s the Codepen of that:</p> <p>See the Pen <a target="_blank" href="https://codepen.io/smashingmag/pen/XWLLbPq" rel="noopener">SVG Polygon / Polyline (JS loop version) [forked]</a> by <a target="_blank" href="https://codepen.io/mynimi" rel="noopener">Myriam</a>.</p> <p>More Fun Stuff</p> <p>Now, that’s all the basics I wanted to cover, but there is so much more you can do with SVG. There is more you can do with <code>transform</code>; you can use a <code>mask</code>, you can use a <code>marker</code>, and so on.</p> <p>We don’t have time to dive into all of them today, but since this started for me when making Calligraphy Grids, I wanted to show you the two most satisfying ones, which I, unfortunately, can’t use in the generator since I wanted to be able to open my generated SVGs in Affinity and it doesn’t support <code>pattern</code>.</p> <p>Okay, so <code>pattern</code> is part of the <code>defs</code> section within the SVG, which is where you can define reusable elements that you can then reference in your SVG.</p> <h3>Graph Grid with <code>pattern</code><br /> </h3> <p>If you think about it, a graph is just a bunch of horizontal and vertical lines that repeat across the x- and y-axis.</p> <p>So, <code>pattern</code> can help us with that. We can create a <code></code> and then reference a <code>pattern</code> in the <code>fill</code> attribute of the <code>rect</code>. The pattern then has its own <code>width</code>, <code>height</code>, and <code>viewBox</code>, which defines how the pattern is repeated.</p> <p>So, let’s say we want to perfectly center our graph grid in any given width or height, and we want to be able to define the size of our resulting squares (cells).</p> <p>Once again, let’s start with the JavaScipt variables:</p> <pre><code>const graphDocWidth = 226; const graphDocHeight = 101; const cellSize = 5; const strokeWidth = 0.3; const strokeColor = "currentColor"; const patternHeight = (cellSize / graphDocHeight) * 100; const patternWidth = (cellSize / graphDocWidth) * 100; const gridYStart = (graphDocHeight % cellSize) / 2; const gridXStart = (graphDocWidth % cellSize) / 2; </code></pre> <p>Now, we can apply them to the SVG element:</p> <pre><code><svg width={svgWidth} viewBox={`0 0 ${graphDocWidth} ${graphDocHeight}`} xmlns="http://www.w3.org/2000/svg" role="img" > <defs> <pattern id="horizontal" viewBox={`0 0 ${graphDocWidth} ${strokeWidth}`} width="100%" height={`${patternHeight}%`} > <line x1="0" x2={graphDocWidth} y1={gridYStart} y2={gridYStart} stroke={strokeColor} stroke-width={strokeWidth} /> </pattern> <pattern id="vertical" viewBox={`0 0 ${strokeWidth} ${graphDocHeight}`} width={`${patternWidth}%`} height="100%" > <line y1={0} y2={graphDocHeight} x1={gridXStart} x2={gridXStart} stroke={strokeColor} stroke-width={strokeWidth} /> </pattern> </defs> <title>A graph grid</title> <rect width={graphDocWidth} height={graphDocHeight} fill="url(#horizontal)" /> <rect width={graphDocWidth} height={graphDocHeight} fill="url(#vertical)" /> </svg> </code></pre> <p>And this is what that then looks like:</p> <p>See the Pen <a target="_blank" href="https://codepen.io/smashingmag/pen/XWLLbxq" rel="noopener">SVG Graph Grid [forked]</a> by <a target="_blank" href="https://codepen.io/mynimi" rel="noopener">Myriam</a>.</p> <h3>Dot Grid With <code>pattern</code><br /> </h3> <p>If we wanted to draw a dot grid instead, we could simply repeat a circle. Or, we could alternatively use a line with a <code>stroke-dasharray</code> and <code>stroke-dashoffset</code> to create a dashed line. And we’d only need one line in this case.</p> <p>Starting with our JavaScript variables:</p> <pre><code>const dotDocWidth = 219; const dotDocHeight = 100; const cellSize = 4; const strokeColor = "black"; const gridYStart = (dotDocHeight % cellSize) / 2; const gridXStart = (dotDocWidth % cellSize) / 2; const dotSize = 0.5; const patternHeight = (cellSize / dotDocHeight) * 100; </code></pre> <p>And then adding them to the SVG element:</p> <pre><code><svg width={svgWidth} viewBox={`0 0 ${dotDocWidth} ${dotDocHeight}`} xmlns="http://www.w3.org/2000/svg" role="img" > <defs> <pattern id="horizontal-dotted-line" viewBox={`0 0 ${dotDocWidth} ${dotSize}`} width="100%" height={`${patternHeight}%`} > <line x1={gridXStart} y1={gridYStart} x2={dotDocWidth} y2={gridYStart} stroke={strokeColor} stroke-width={dotSize} stroke-dasharray={`0,${cellSize}`} stroke-linecap="round" ></line> </pattern> </defs> <title>A Dot Grid</title> <rect x="0" y="0" width={dotDocWidth} height={dotDocHeight} fill="url(#horizontal-dotted-line)" ></rect> </svg> </code></pre> <p>And this is what that looks like:</p> <p>See the Pen <a target="_blank" href="https://codepen.io/smashingmag/pen/eYwwNQM" rel="noopener">SVG Dot Grid [forked]</a> by <a target="_blank" href="https://codepen.io/mynimi" rel="noopener">Myriam</a>.</p> <p>Conclusion</p> <p>This brings us to the end of our little introductory journey into SVG. As you can see, coding SVG by hand is not as scary as it seems. If you break it down into the basic elements, it becomes quite like any other coding task:</p> <ul> <li>We analyze the problem,</li> <li>Break it down into smaller parts,</li> <li>Examine each coordinate and its mathematical breakdown,</li> <li>And then put it all together.</li> </ul> <p>I hope that this article has given you a starting point into the wonderful world of coded images and that it gives you the motivation to delve deeper into the specs and try drawing some yourself.</p> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://www.webmastersgallery.com/category/uncategorized/" rel="category tag">Others</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <div class="post" id="post-7122959"> <h2><a class="title" href="http://www.webmastersgallery.com/2024/09/17/clever-polypane-debugging-features-im-loving/" rel="bookmark">Clever Polypane Debugging Features I’m Loving</a></h2> <div class="info"> <span class="date">September 17th, 2024</span> <span class="author"><a href="http://www.webmastersgallery.com/author/admin/" title="Posts by admin" rel="author">admin</a></span> <span class="comments"><a href="http://www.webmastersgallery.com/2024/09/17/clever-polypane-debugging-features-im-loving/#respond">No comments</a></span> <div class="fixed"></div> </div> <div class="content"> <div class="ftpimagefix" style="float:left"><a target="_blank" href="1" rel="noopener"><img decoding="async" data-recalc-dims="1" loading="lazy" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/polypane-1.jpg?resize=1908%2C1019&ssl=1" alt="Polypane browser displaying ryantrimble.com in three different viewport sizes simultaneously" class="wp-image-380565"></a></div> <p>I’m working on a refresh of my personal website, what I’m calling the <em>HD remaster</em>. Well, I wouldn’t call it a “full” redesign. I’m just cleaning things up, and <a target="_blank" href="https://polypane.app/" rel="noopener">Polypane</a> is coming in clutch. I wrote about how much I enjoy developing with Polypane <a target="_blank" href="https://ryantrimble.com/blog/building-with-polypane/" rel="noopener">on my personal blog</a> back in March 2023. In there, I say that I discover new things every time I open the browser up and I’m here to say that is <em>still happening</em> as of August 2024.</p> <p>Polypane, in case you’re unfamiliar with it, is a web browser specifically created to help developers in all sorts of different ways. The most obvious feature is the multiple panes displaying your project in various viewport sizes:</p> <p><span></span></p> <div class="wp-block-image"> <figure class="aligncenter size-full"></figure> </div> <p>I’m not about to try to list every feature available in Polypane; I’ll leave that to friend and creator, <a target="_blank" href="https://kilianvalkhof.com/" rel="noopener">Kilian Valkhof</a>. Instead, I want to talk about a neat feature that I discovered recently.</p> <h3 class="wp-block-heading">Outline tab</h3> <p>Inside Polypane’s sidebar, you will find various tabs that provide different bits of information about your site. For example, if you are wondering how your social media previews will look for your latest blog post, Polypane has you covered in the <strong>Meta</strong> tab.</p> <div class="wp-block-image"> <figure class="aligncenter size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="482" height="394" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/polypane-2.jpg?resize=482%2C394&ssl=1" alt="Preview card displaying how open graph information will display on Mastodon." class="wp-image-380568"></figure> </div> <p>The tab I want to focus on though, is the <strong>Outline</strong> tab. On the surface, it seems rather straightforward, Polypane scans the page and provides you outlines for headings, landmarks, links, images, focus order, and even the full page accessibility tree.</p> <div class="wp-block-image"> <figure class="aligncenter size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="443" height="313" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/polypane-3.jpg?resize=443%2C313&ssl=1" alt="Polypane sidebar, outline tab, the view select options display the different views available: Headings, Landmarks, Links, Images, Focus order, and Accessibility Tree" class="wp-image-380570"></figure> </div> <p>Seeing your page this way helps you spot some pretty obvious mistakes, but Polypane doesn’t stop there. Checking the <strong>Show issues</strong> option will point out some of the not-so-obvious problems.</p> <div class="wp-block-image"> <figure class="aligncenter size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="444" height="307" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/polypane-4.jpg?resize=444%2C307&ssl=1" alt='Polypane sidebar, outline tab, Landsmarks view, the "Show issues" option is enabled. In the outline, red text describes an error: Multiple banner elements at the same level found.' class="wp-image-380572"></figure> </div> <p>In the Landmarks view, there is an option to <strong>Show potentials</strong> as well, which displays elements that could <em>potentially</em> be page landmarks.</p> <div class="wp-block-image"> <figure class="aligncenter size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="419" height="86" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/polypane-5.png?resize=419%2C86&ssl=1" alt="Polypane sidebar, Outline tab, Landmark view - the outline displays a red symbol indicating a potential landmark element" class="wp-image-380573"></figure> </div> <p>In these outline views, you also can show an overlay on the page and highlight where things are located.</p> <div class="wp-block-image"> <figure class="aligncenter size-large"><img decoding="async" data-recalc-dims="1" loading="lazy" width="1024" height="492" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/polypane-6.jpg?resize=1024%2C492&ssl=1" alt="Polypane laptop viewport view of ryantrimble.com, the landmark overlay feature is enabled, which outlines landmark elements in blue while also displaying their value" class="wp-image-380574"></figure> </div> <p>Now, the reason I even stumbled upon these features within the Outline tab is due to a bug I was tracking down, one specifically related to focus order. So, I swapped over to the “Focus order” outline to inspect things further.</p> <div class="wp-block-image"> <figure class="aligncenter size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="447" height="351" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/polypane-7.jpg?resize=447%2C351&ssl=1" alt="Polypane sidebar, outline tab, Focus order view, displays an outline of the focusable elements on the page" class="wp-image-380575"></figure> </div> <p>That’s when I noticed the option to see an overlay <em>for the focus order</em>.</p> <div class="wp-block-image"> <figure class="aligncenter size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="1391" height="847" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/polypane-8-1.jpg?resize=1391%2C847&ssl=1" alt="Polypane laptop view with focus order overlay enabled, displays guide lines marking the location of each focusable items" class="wp-image-380580"></figure> </div> <p>This provides a literal map of the focus order of your page. I found this to be incredibly useful while troubleshooting the bug, as well as a great way to visualize how someone might navigate your website using a keyboard.</p> <p>These types of seemingly small, but useful features are abundant throughout Polypane. </p> <h3 class="wp-block-heading">Amazing tool</h3> <p>When I reached out to Kilian, mentioning my discovery, his response was “Everything’s there when you need it!” </p> <p>I can vouch for that.</p> <hr> <p><small><a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/clever-polypane-debugging-features-im-loving/">Clever Polypane Debugging Features I’m Loving</a> originally published on <a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/">CSS-Tricks</a>, which is part of the <a target="_blank" href="https://try.digitalocean.com/css-tricks/?utm_medium=rss&utm_source=css-tricks.com&utm_campaign=family_&utm_content=" rel="noopener">DigitalOcean</a> family. You should <a target="_blank" href="https://css-tricks.com/newsletters/" rel="noopener">get the newsletter</a>.</small></p> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://www.webmastersgallery.com/category/design/" rel="category tag">Designing</a>, <a href="http://www.webmastersgallery.com/category/uncategorized/" rel="category tag">Others</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <div class="post" id="post-7122784"> <h2><a class="title" href="http://www.webmastersgallery.com/2024/09/17/why-is-risk-management-important-to-underwriters/" rel="bookmark">Why is risk management important to underwriters?</a></h2> <div class="info"> <span class="date">September 17th, 2024</span> <span class="author"></span> <span class="comments"><a href="http://www.webmastersgallery.com/2024/09/17/why-is-risk-management-important-to-underwriters/#respond">No comments</a></span> <div class="fixed"></div> </div> <div class="content"> <div class="ftpimagefix" style="float:left"><a target="_blank" href="0" rel="noopener"><img decoding="async" src="https://www.noupe.com/wp-content/uploads/2024/09/loic-leray-fCzSfVIQlVY-unsplash-1024x681.jpg" class="attachment-large size-large wp-post-image" alt=""></a></div> <div></div> <p class="opener">“An uncontrollable, potential lack of something valuable” is a fundamental definition of risk. The foundation of the insurance industry is based on the idea of risk and its sharing, in which an insurer takes on part of the monetary hazard of an insured celebration in return for a predetermined amount of money referred to as a top class. Underwriters are essential to the insurance sector as they determine the types and conditions of insurance coverage. Their duty is to evaluate the risk in imparting coverage to individuals, businesses, and assets and to make decisions that might be consistent with the risk tolerance of an insurer.</p> <p>As a result, risk management will become a critical step in the underwriting process, ensuring the commercial enterprise’s enduring profitability and policyholder protection. In this sense, a robust <a target="_blank" href="https://newgensoft.com/insurance-underwriting/" rel="noreferrer noopener" data-wpel-link="external">insurance underwriting system</a> is important because it permits underwriters to assess risk successfully and make knowledgeable choices. In this blog, we will highlight the importance of risk management to underwriters and how leveraging cutting-edge underwriting structures complements this important procedure.</p> <h2 class="wp-block-heading"><strong>Importance of Risk Management in Underwriting</strong></h2> <h3 class="wp-block-heading">Preserving Monetary Stability</h3> <p>Insurance’s essential purpose is to guard against financial loss, and risk control is vital to preserving the insurer’s economic balance. Underwriters ensure that charges are enough to pay for future claims as well as administrative expenses by precisely determining the risk stage connected with every policy. This meticulous risk management provides a solid foundation for the insurer’s financial stability, reassuring policyholders.</p> <p>Underwriters can better control this using predictive models from a systematic insurance underwriting system. These systems compute future risk based on past data, outside assets, and real-time inputs. This prevents the insurer from taking on more risk than necessary to maintain long-term sustainability and profitability.</p> <h3 class="wp-block-heading">2. Avoiding Unfavorable Selection</h3> <p>People or corporations are much more likely to get insurance when the risk is excessive. In contrast, low-risk individuals might also select not to, which is referred to as detrimental selection. Underwriters play a crucial role in addressing this imbalance, ensuring that claims do not exceed expectations and thereby maintaining the insurer’s profitability. Their efforts instill confidence in the fairness and sustainability of the insurance system.</p> <p>Underwriters can reduce adverse selection by employing data-driven insights and comprehensive risk profiles provided by risk management. <a target="_blank" href="https://developers.google.com/machine-learning/crash-course" rel="noreferrer noopener" data-wpel-link="external">Machine learning programs</a> can be integrated into an insurance underwriting system to identify and predict high-risk policyholders. This allows underwriters to determine suitable premiums or, in extreme cases, cancel coverage.</p> <h3 class="wp-block-heading">3. Improving Pricing Based on Risk</h3> <p>Underwriters can use risk-based pricing when they have <a target="_blank" href="https://www.noupe.com/business-online/doing-efficient-risk-management-in-5-steps.html" rel="noreferrer noopener" data-wpel-link="internal">effective risk management</a> in place. With this technique, insurers can charge higher premiums to consumers with more significant risks while offering more competitive rates to low-risk customers. This pricing strategy enhances the insurer’s capacity to attract low-risk customers and maintain profitability.</p> <p>A progressive underwriting device makes dynamic insurance pricing based on the individual traits of every policyholder viable. To help underwriters best-tune pricing methods, it integrates many records sources, such as credit scores, medical histories, and driving statistics.</p> <h3 class="wp-block-heading"><strong>4. Increasing the Efficiency of Underwriting</strong></h3> <p>An effective insurance underwriting system and risk control make the system run more smoothly. Underwriters can handle harsh conditions using automatic risk evaluation structures to perform repetitive duties like records collection, background assessments, and simple danger critiques.</p> <p>By automating regular chance management responsibilities, underwriters may additionally process more policies in less time without compromising on accuracy. This is crucial because insurers must process packages fast while upholding risk standards in an increasingly competitive marketplace.</p> <h2 class="wp-block-heading"><strong>The Role of Technology in Risk Management</strong></h2> <p>In the cutting-edge insurance landscape, technology has revolutionized danger management practices in underwriting. An insurance underwriting system with advanced technologies such as artificial intelligence (AI), machine studying (ML), and big data analytics enables underwriters to make better-informed choices.</p> <h3 class="wp-block-heading"><strong>1. Predictive Analytics together with Risk Analysis</strong></h3> <p>One of the technologies revolutionizing risk management the most is predictive analytics. Historical data must be analyzed to forecast future events. Predictive models in underwriting assist underwriters in adjusting premiums or policy terms by predicting the likelihood of a claim.</p> <p>Modern<strong> </strong>insurance underwriting systems incorporate real-time data from external sources, such as social media, satellite imaging, and economic indicators, into prediction models. This allows underwriters to evaluate risks more precisely, even in ambiguous situations.</p> <h3 class="wp-block-heading"><strong>2. Fraud Identification</strong></h3> <p>Fraudulent claims may severely damage insurance firms. Identifying and mitigating fraud risk throughout the underwriting process is a crucial aspect of risk management.</p> <p>A coverage underwriting gadget can use artificial intelligence (AI) algorithms to identify positions that might imply fraud. For example, the gadget can also highlight a risk for additional examination through an underwriter if the prospective policyholder offers conflicting records or has a questionable claims history. This lessens the possibility of underwriting fraud-susceptible guidelines.</p> <h3 class="wp-block-heading"><strong>3. AI and Automation-Powered Decision Making</strong></h3> <p>Underwriters can better cope with large quantities of statistics and make brief, facts-driven alternatives, while positive aspects of the risk management process are automated using AI and machine learning. With AI algorithms, every coverage will undergo a comprehensive hazard appraisal in seconds, which could evaluate chance factors much more quickly than a human underwriter.</p> <h2 class="wp-block-heading"><strong>Conclusion</strong></h2> <p>Underwriters need to be adept at risk control because it has an immediate bearing on insurance agencies’ fitness, viability, and expansion. By using sophisticated coverage underwriting systems and effective threat control strategies, underwriters may make well-informed judgments, reduce risks, and guarantee that premiums are reasonably priced.</p> <p>Adopting generation and facts-pushed insights could be crucial for future success in a quickly converting industry. The better risk control equipment gets, the greater the underwriters can be and the more ready they are to address the challenges of an increasing number of complicated insurance panoramas.</p> <p><em>Featured image by <a target="_blank" href="https://unsplash.com/@loicleray?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash" rel="noreferrer noopener nofollow" data-wpel-link="external">Loic Leray</a> on <a target="_blank" href="https://unsplash.com/photos/man-on-rope-fCzSfVIQlVY?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash" rel="noreferrer noopener nofollow" data-wpel-link="external">Unsplash</a></em></p> <p>The post <a target="_blank" href="https://www.noupe.com/business-online/why-is-risk-management-important-to-underwriters.html" data-wpel-link="internal" rel="noopener">Why is risk management important to underwriters?</a> appeared first on <a target="_blank" href="https://www.noupe.com/" data-wpel-link="internal" rel="noopener">noupe</a>.</p> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://www.webmastersgallery.com/category/uncategorized/" rel="category tag">Others</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <div class="post" id="post-7122960"> <h2><a class="title" href="http://www.webmastersgallery.com/2024/09/17/creating-custom-lottie-animations-with-svgator/" rel="bookmark">Creating Custom Lottie Animations With SVGator</a></h2> <div class="info"> <span class="date">September 17th, 2024</span> <span class="author"></span> <span class="comments"><a href="http://www.webmastersgallery.com/2024/09/17/creating-custom-lottie-animations-with-svgator/#respond">No comments</a></span> <div class="fixed"></div> </div> <div class="content"> <div class="ftpimagefix" style="float:left"><a target="_blank" href="0" rel="noopener"><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/4-animation-svgator.gif"></a></div> <p>This article is a sponsored by <a target="_blank" href="https://www.svgator.com/?utm_source=smashingmagazine.com&utm_medium=referral&utm_campaign=lottie-article" rel="noopener">SVGator</a></p> <p>SVGator has gone through a series of updates since our last article, which was published in 2021, when it was already considered to be the most advanced web-based tool for vector animation. The first step toward more versatile software came with the mobile export feature that made it possible to implement the animations in iOS and Android applications.</p> <p>The animation tool continued its upgrade with a series of new export options: video formats including MP4, AVI, MKV, MOV, and WebM, as well as image formats such as GIF, Animated PNG, WebP, and image sequence. By covering a larger area of users’ needs, the app now enables anyone to create animated stickers, social media, and newsletter animations, video assets, and many more types of visual content on demand.</p> <p>The goal of becoming a “one tool for all” still lacked the last piece of the puzzle, namely full support for Lottie files. Lottie, just like SVG, is a vector-based format, but it has even <strong>better comprehensive multi-platform support</strong>, a fact that makes it super popular among developers and design professionals. It is built for use across various platforms, enabling <strong>smooth integration into both web and mobile applications</strong>. Its file size is minimal, it is <strong>infinitely scalable</strong>, and developers find it straightforward to implement once they get familiar with the format. Lottie can incorporate raster graphics and also supports interactivity.</p> <p>SVGator’s latest version has everything you need for your various applications without the need for any third-party apps or plug-ins.</p> <p><strong>Note</strong>: <em>You can test all of SVGator’s functionalities free of charge before committing to the Pro plan. However, you can export up to three watermarked files, with videos and GIFs limited to basic quality.</em></p> <p>In this article, we will follow a creation process made of these steps:</p> <ul> <li>Importing an existent Lottie JSON and making some minor adjustments;</li> <li>Importing new animated assets created with SVGator (using the library);</li> <li>Creating and animating new elements from scratch;</li> <li>Exporting the Lottie animation.</li> </ul> <p>Getting Started With SVGator</p> <p>The sign-up process is simple, fast, and straightforward, and no credit card is required. Sign up either with Google or Facebook or, alternatively, by providing your name, email address, and password. Start a project either with a Lottie animation or a static SVG. If you don’t have an existing file, you can design and animate everything starting from a blank canvas.</p> <p>Now that you’ve created your account, let’s dive right into the fun part. Here’s a preview of how your animation is going to look by the time you’re done following this guide. Neat, right?</p> <p>(<a target="_blank" href="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/1-final-animation.gif" rel="noopener">Large preview</a>)</p> <p>Create A New Project</p> <p>After logging in and clicking on the <strong>New Project</strong> option, you will be taken to the <strong>New Project Panel</strong>, where you can choose between starting from a blank project or uploading a file. Let’s start this project with an existing Lottie JSON.</p> <ul> <li><a target="_blank" href="https://cdn.svgator.com/assets/pub/fast-response.json" rel="noopener">Download the Lottie demo</a></li> </ul> <ol> <li>Click on the <strong>Upload file</strong> button and navigate to the directory where you have saved your Lottie file. <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/3-lottie-open-file.png"> </li> <li>Select the “<strong>Fast response.json</strong>” file and click <strong>Open</strong>. <p>Hit play in the editor, and the animation should look like this:</p> <p><a target="_blank" href="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/4-animation-svgator.gif" rel="noopener"><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/4-animation-svgator.gif"></a>(<a target="_blank" href="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/4-animation-svgator.gif" rel="noopener"><em>Large preview</em></a>) </li> </ol> <p><strong>Note</strong>: <em>Make sure to hit</em> <strong><em>Save</em></strong> <em>after each step to make sure you don’t lose any of your progress while working on this project alongside our guide.</em></p> <p>Import An Animated Asset</p> <p>In this step, you will learn how to use the <strong>Library</strong> to import new assets to your project. You can easily choose from a variety of ready-made SVGs stored in different categories, load new files from your computer (Lottie, static SVG, and images), or save animations from other SVGator projects and reuse them.</p> <p>In this case, let’s use an animated message bubble previously created and saved to the <strong>Uploads</strong> section of the <strong>Library</strong>.</p> <p>Learn how to <strong>create and save animated assets</strong> with this <a target="_blank" href="https://www.youtube.com/watch?v=R2Px90nfOEI" rel="noopener">short video tutorial</a>.</p> <ul> <li><a target="_blank" href="https://cdn.svgator.com/assets/pub/message-bubble.json" rel="noopener">Download the message bubble Lottie animation</a></li> </ul> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/5-message-bubble-lottie-animation.png"></p> <ol> <li>Navigate to the left sidebar of the app and switch to the Library tab, then click the “+” icon to upload the message bubble asset that you downloaded earlier.</li> <li>After it is loaded in the uploads section, simply click on it to add it to your project. <p>All the animated properties of the asset are now present in the timeline, and you can edit them if you want.</p> <p><strong>Note</strong>: <em>Make sure the playhead is at the second “0” before adding the animated asset. When adding an animated asset, it will always start animating from the point where the playhead is placed.</em> </li> <li>Freely adjust its position and size as you wish.</li> <li>With the playhead at the second 0, click on the <strong>Animate</strong> button, then choose <strong>Position</strong>.</li> </ol> <p>At this point, you should have the first Position keyframe automatically added at the second 0, and you are ready to start animating. </p> <p>Animate The Message Bubble</p> <ol> <li>Start by dragging the playhead on the timeline at 0.2 seconds: <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/6-animate-message-bubble.png"> </li> <li>Then, drag the message bubble up a few pixels. The second keyframe will appear in the timeline, marking the element’s new position, thus creating the 2 milliseconds animation. <p><strong>Note</strong>: <em>You can hit Play at any moment to check how everything looks!</em></p> <p>Next, you can use the Scale animator to make the bubble disappear after the dots representing the typing are done animating by scaling it down to 0 for both the X and Y axes:</p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/7-animate-message-bubble.png"> </li> <li>With the message bubble still selected, drag the playhead at 2.2 seconds, click on <strong>Animate</strong>, and select Scale (or just press Shift + S on the keyboard) to set the first Scale keyframe, then drag the playhead at 2.5 seconds.</li> <li>Set the scale properties to 0 for both the X and Y axes (in the right side panel). The bubble won’t be visible anymore at this point. <p><strong>Note</strong>: <em>To maintain the ratio while changing the scale values, make sure you have the Maintain proportions on (the link icon next to the scale inputs).</em></p> <p>To add an extra touch of interest to this scaling motion, add an easing function preset:</p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/8-animate-message-bubble.png"> </li> <li>First, jump back to the first Scale keyframe (you can also double-click the keyframe to jump the playhead right at it).</li> <li>Open the <strong>Easing Panel</strong> next to the time indicator and scroll down through the presets list, then select <strong>Ease in Back</strong>. Due to its bezier going out of the graph, this easing function will create a bounce-back effect for the scale animation. <p><strong>Note</strong>: <em>You can adjust the bezier of a selected easing preset and create a new custom function, which will appear at the top of the list.</em></p> <p><em>Keep in mind that you need at least one keyframe selected if you intend to apply an easing. The easing function will apply from the selected keyframe toward the next keyframe at its right. Of course, you can apply a certain easing for multiple keyframes at once.</em></p> <p>To get a smoother transition when the message bubble disappears, add an Opacity animation of one millisecond at the end of the scaling:</p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/9-animate-message-bubble.png"> </li> <li>Choose <strong>Opacity</strong> from the animators’ list and set the first keyframe at 2.4 seconds, then drag the playhead at 2.5 seconds to match the ending keyframe from the scale animation above.</li> <li>From the <strong>Appearance panel</strong>, drag the <strong>Opacity slider</strong> all the way to the left, at 0%.</li> </ol> <p>Create An Email Icon</p> <p>For the concept behind this animation to be complete, let’s create (and later animate) a “new email” notification as a response to the character sending that message.</p> <p>Once again, SVGator’s asset library comes in handy for this step:</p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/10-create-email-icon-animation.png"></p> <ol> <li>Go to the search bar from the <strong>Library</strong> and type in “<strong>mail</strong>,” then click on the mail asset from the results.</li> <li>Place it somewhere above the laptop. Edit the mail icon to better fit the style of the animation: <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/11-edit-mail-icon-animation.png"> </li> <li>Open the <strong>email</strong> group and select the rectangle from the back.</li> <li>Change its fill color to a dark purple.</li> <li>Round up the corners using the <strong>Radius</strong> slider. <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/12-edit-mail-icon-animation.png"> </li> <li>Make the element’s design minimal by deleting these two lines from the lower part of the envelope. <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/13-edit-mail-icon-animation.png"> </li> <li>Select the envelope seal flap, which is the <strong>Polyline</strong> element in the group, above the rectangle.</li> <li>Add a lighter purple for the fill, set the stroke to 2 px width, and also make it white. <p>To make the animation even more interesting, create a notification alert in the top-right corner of the envelope:</p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/14-edit-mail-icon-animation.png"> </li> <li>Use the <strong>Ellipse tool (O)</strong> from the toolbar on top and draw a circle in the top-right corner of the envelope.</li> <li>Choose a nice red color for the fill, and set the stroke to white with a 2 px width. <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/15-edit-mail-icon-animation.png"> </li> <li>Click on the “T” icon to select the <strong>Text</strong> tool.</li> <li>Click on the circle and type “1”.</li> <li>Set the color to white and click on the “B” icon to make it bold. <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/16-edit-mail-icon-animation.png"> </li> <li>Select both the red circle and the number, and group them: right-click, and hit <strong>Group</strong>. <p>You can also hit Command or Ctrl + G on your keyboard. Double-click on the newly created group to rename it to “Notification.”</p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/17-edit-mail-icon-animation.png"> </li> <li>Select both the notification group and email group below and create a new group, which you can name “new email.”</li> </ol> <p>Animate The New Email Group</p> <p>Let’s animate the new email popping out of the laptop right after the character has finished texting his message:</p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/18-animate-new-email-group.png"></p> <ol> <li>With the “New email” group selected, click twice on the <strong>Move down</strong> icon from the header to place the group last.<br />You can also press Command or Ctrl + arrow down on your keyboard.</li> <li>Drag the group behind the laptop (on the canvas) to hide it entirely, and also scale it down a little.</li> <li>With the playhead at 3 seconds, add the animators <strong>Scale</strong> and <strong>Position</strong>.<br />You can also do that by pressing Shift + S and Shift + P on your keyboard. <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/19-animate-new-email-group.png"> </li> <li>Drag the playhead at the second 3.3 on the timeline.</li> <li>Move the New Email group above the laptop and scale it up a bit.</li> <li>You can also bend the motion path line to create a curved trajectory for the position animation. <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/20-animate-new-email-group.png"> </li> <li>Select the first keyframes at the second 3.</li> <li>Open the easing panel.</li> <li>And click on the <strong>Ease Out Cubic</strong> preset to add it to both keyframes.</li> </ol> <p>Animate The Notification</p> <p>Let’s animate the notification dot separately. We’ll make it pop in while the email group shows up. </p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/21-animate-notification.png"></p> <ol> <li>Select the <strong>Notification</strong> group.</li> <li>Create a scale-up animation for it with 0 for both the X and Y axes at 3.2 and 1 at 3.5 seconds.</li> <li>Select the first keyframe and, from the easing panel, choose <strong>Ease Out Back</strong>. This easing function will ensure the popping effect.</li> </ol> <p>Add Expressiveness To The Character</p> <p>Make the character smile while looking at the email that just popped out. For this, you need to animate the stroke offset of the mouth:</p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/22-add-expressiveness-character.png"></p> <ol> <li>Select the mouth path. You can use the <strong>Node tool</strong> to select it directly with one click.</li> <li>Drag the playhead at 3.5 seconds, which is the moment from where the smile will start.</li> <li>Select the last keyframe of the <strong>Stroke offset</strong> animator from the timeline and duplicate it at second 3.5, or you can also use Ctrl or Cmd + D for duplication. <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/23-add-expressiveness-character.png"> </li> <li>Drag the playhead at second 3.9.</li> <li>Go to the properties panel and set the Offset to 0. The stroke will now fill the path all the way, creating a stroke offset animation of 4 milliseconds.</li> </ol> <p>Final Edits</p> <p>You can still make all kinds of adjustments to your animation before exporting it. In this case, let’s change the color of the initial Lottie animation we used to start this project:</p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/24-final-edits-color.png"></p> <ol> <li>Use the <strong>Node tool</strong> to select all the green paths that form the character’s arms and torso.</li> <li>Change the color as you desire.</li> </ol> <p>Export Lottie</p> <p>Once you’re done editing, you can export the animation by clicking on the top right <strong>Export</strong> button and selecting the Lottie format. Alternatively, you can press Command or Ctrl + E on your keyboard to jump directly to the export panel, from where you can still select the animation you want to export.</p> <p><img decoding="async" src="https://files.smashing.media/articles/creating-custom-lottie-animations-svgator/25-export-lottie.png"></p> <ol> <li>Make sure the Lottie format is selected from the dropdown. In the export panel, you can set a name for the file you are about to export, choose the frame rate and animation speed, or set a background color.</li> <li>You can preview the Lottie animation with a Lottie player.<br /><strong>Note</strong>: <em>This step is recommended to make sure all animations are supported in the Lottie format by previewing it on a webpage using the Lottie player. The preview in the export panel isn’t an actual Lottie animation.</em> </li> <li>Get back to the export panel and simply click <strong>Export</strong> to download the Lottie JSON.</li> </ol> <p>Final Thoughts</p> <p>Now that you’re done with your animation don’t forget that you have plenty of export options available besides Lottie. You can post the same project on social media in video format, export it as an SVG animation for the web, or turn it into a GIF sticker or any other type of visual you can think of. GIF animations can also be used in Figma presentations and prototypes as a high-fidelity preview of the production-ready Lottie file.</p> <p>We hope you enjoyed this article and that it will inspire you to create amazing Lottie animations in your next project. </p> <p>Below, you can find a few useful resources to continue your journey with SVG and SVGator:</p> <ul> <li> <a target="_blank" href="https://www.svgator.com/tutorials?utm_source=smashingmagazine.com&utm_medium=referral&utm_campaign=lottie-article" rel="noopener">SVGator tutorials</a><br />Check out a series of short video tutorials to help you get started with SVGator.</li> <li> <a target="_blank" href="https://www.svgator.com/help?utm_source=smashingmagazine.com&utm_medium=referral&utm_campaign=lottie-article" rel="noopener">SVGator Help Center</a><br />It answers the most common questions about SVGator, its features, and membership plans.</li> </ul> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://www.webmastersgallery.com/category/uncategorized/" rel="category tag">Others</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <div class="post" id="post-7121178"> <h2><a class="title" href="http://www.webmastersgallery.com/2024/09/16/multiple-anchors/" rel="bookmark">Multiple Anchors</a></h2> <div class="info"> <span class="date">September 16th, 2024</span> <span class="author"><a href="http://www.webmastersgallery.com/author/admin/" title="Posts by admin" rel="author">admin</a></span> <span class="comments"><a href="http://www.webmastersgallery.com/2024/09/16/multiple-anchors/#respond">No comments</a></span> <div class="fixed"></div> </div> <div class="content"> <p>Only Chris, right? You’ll want to view this in a Chromium browser:</p> <div class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper">CodePen Embed Fallback</div> <p>This is exactly the sort of thing I love, not for its practicality (cuz it ain’t), but for how it illustrates a concept. Generally, tutorials and demos try to follow the “rules” — whatever those may be — yet breaking them helps you understand how a certain thing works. This is one of those.</p> <p><span></span></p> <p>The concept is pretty straightforward: one target element can be attached to multiple <a target="_blank" href="https://css-tricks.com/almanac/functions/a/anchor-name/" rel="noopener">anchors</a> on the page.</p> <pre class="wp-block-csstricks-code-block language-markup" data-line=""><code><div class="anchor-1"></div> <div class="anchor-2"></div> <div class="target"></div></code></pre> <p>We’ve gotta register the anchors and attach the <code>.target</code> to them:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>.anchor-1 { anchor-name: --anchor-1; } .anchor-2 { anchor-name: --anchor-2; } .target { }</code></pre> <p><em>Wait, wait!</em> I didn’t attach the <code>.target</code> to the anchors. That’s because we have two ways to do it. One is <strong>using the <code><a target="_blank" href="https://css-tricks.com/almanac/properties/p/position-anchor/" rel="noopener">position-anchor</a></code> property</strong>.</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>.target { position-anchor: --anchor-1; }</code></pre> <p>That establishes a target-anchor relationship between the two elements. But it only accepts a single anchor value. <em>Hmm. We need more than that.</em> That’s what the <code><a target="_blank" href="https://css-tricks.com/almanac/properties/a/anchor/" rel="noopener">anchor()</a></code> function can do. Well, it doesn’t take multiple values, but we can declare it multiple times on different inset properties, each referencing a different anchor.</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>.target { top: anchor(--anchor-1, bottom); }</code></pre> <p>The second piece of <code>anchor()</code>‘s function is the anchor edge we’re positioned to and it’s gotta be <a target="_blank" href="https://css-tricks.com/almanac/functions/a/anchor/#aa-arguments" rel="noopener">some sort of physical or logical inset</a> — <code>top</code>, <code>bottom</code>, <code>start</code>, <code>end</code>, <code>inside</code>, <code>outside</code>, etc. — or percentage. We’re bascially saying, “Take that <code>.target</code> and slap it’s <code>top</code> edge against <code>--anchor-1</code>‘s bottom edge.</p> <p>That also works for other inset properties:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>.target { top: anchor(--anchor-1 bottom); left: anchor(--anchor-1 right); bottom: anchor(--anchor-2 top); right: anchor(--anchor-2 left); }</code></pre> <p>Notice how both anchors are declared on different properties by way of <code>anchor()</code>. That’s rad. But we aren’t actually anchored yet because the <code>.target</code> is just like any other element that participates in the normal document flow. We have to yank it out with absolute positioning for the inset properties to take hold.</p> <pre class="wp-block-csstricks-code-block language-css" data-line="2"><code>.target { position: absolute; top: anchor(--anchor-1 bottom); left: anchor(--anchor-1 right); bottom: anchor(--anchor-2 top); right: anchor(--anchor-2 left); }</code></pre> <p>In his demo, Chris cleverly attaches the <code>.target</code> to two <code><textarea></code> elements. What makes it clever is that <code><textarea></code> allows you to click and drag it to change its dimensions. The two of them are absolutely positioned, one pinned to the viewport’s top-left edge and one pinned to the bottom-right.</p> <p>If we attach the <code>.target's top</code> and <code>left</code> edges to <code>--anchor-1</code>‘s <code>bottom</code> and <code>right</code> edges, then attach the <code>target's bottom</code> and <code>right</code> edges to <code>--anchor-2</code>‘s <code>top</code> and <code>left</code> edges, we’re effectively anchored to the two <code><textarea></code> elements. This is what allows the <code>.target</code> element to stretch with the <code><textarea></code> elements when they are resized.</p> <p>But there’s a small catch: a <code><textarea></code> is resized from its bottom-right corner. The second <code><textarea></code> is positioned in a way where the resizer isn’t directly attached to the <code>.target</code>. If we <code>rotate(180deg)</code>, though, it’s all good.</p> <div class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper">CodePen Embed Fallback</div> <p>Again, you’ll want to view that in a Chromium browser at the time I’m writing this. Here’s a clip instead if you prefer.</p> <figure class="wp-block-video"><video controls src="https://css-tricks.com/wp-content/uploads/2024/09/multiple-anchors.mov" playsinline preload="none"></video></figure> <p>That’s just a <code>background-color</code> on the <code>.target</code> element. We can put a little character in there instead as a <code>background-image</code> like Chris did to polish this off.</p> <div class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper">CodePen Embed Fallback</div> <figure class="wp-block-video"><video controls src="https://css-tricks.com/wp-content/uploads/2024/09/multiple-anchors-gumby.mov" playsinline preload="none"></video></figure> <p>Fun, right?! It still blows my mind this is all happening in CSS. It wasn’t many days ago that something like this would’ve been a job for JavaScript.</p> </p> <hr> <p><small><a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/multiple-anchors/">Multiple Anchors</a> originally published on <a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/">CSS-Tricks</a>, which is part of the <a target="_blank" href="https://try.digitalocean.com/css-tricks/?utm_medium=rss&utm_source=css-tricks.com&utm_campaign=family_&utm_content=" rel="noopener">DigitalOcean</a> family. You should <a target="_blank" href="https://css-tricks.com/newsletters/" rel="noopener">get the newsletter</a>.</small></p> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://www.webmastersgallery.com/category/design/" rel="category tag">Designing</a>, <a href="http://www.webmastersgallery.com/category/uncategorized/" rel="category tag">Others</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <div class="post" id="post-7121179"> <h2><a class="title" href="http://www.webmastersgallery.com/2024/09/16/smashing-hour-with-lynn-fisher/" rel="bookmark">Smashing Hour With Lynn Fisher</a></h2> <div class="info"> <span class="date">September 16th, 2024</span> <span class="author"><a href="http://www.webmastersgallery.com/author/admin/" title="Posts by admin" rel="author">admin</a></span> <span class="comments"><a href="http://www.webmastersgallery.com/2024/09/16/smashing-hour-with-lynn-fisher/#respond">No comments</a></span> <div class="fixed"></div> </div> <div class="content"> <p>I’m a big Lynn Fisher fan. You probably are, too, if you’re reading this. Or maybe you’re reading her name for the first time, in which case you’re in for a treat.</p> <p>That’s because I had a chance to sit down with Lynn for a whopping hour to do nothing more than gab, gab, and gab some more. I love these little Smashing Hours because they’re informal like that and I feel like I really get to know the person I’m talking with. And this was my very first time talking with Lynn, we had a ton to talk about — her CSS art, her annual site refreshes, where she finds inspiration for her work, when the web started to “click” for her… and so much more.</p> <p><span></span></p> <figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"> <div class="wp-block-embed__wrapper"> </div> </figure> <p>Don’t miss the bit where Lynn discusses <a target="_blank" href="https://lynnandtonic.com/" rel="noopener">her current site design</a> (~24 min.) because it’s a masterclass in animation and creativity.</p> <hr> <p><small><a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/smashing-hour-with-lynn-fisher/">Smashing Hour With Lynn Fisher</a> originally published on <a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/">CSS-Tricks</a>, which is part of the <a target="_blank" href="https://try.digitalocean.com/css-tricks/?utm_medium=rss&utm_source=css-tricks.com&utm_campaign=family_&utm_content=" rel="noopener">DigitalOcean</a> family. You should <a target="_blank" href="https://css-tricks.com/newsletters/" rel="noopener">get the newsletter</a>.</small></p> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://www.webmastersgallery.com/category/design/" rel="category tag">Designing</a>, <a href="http://www.webmastersgallery.com/category/uncategorized/" rel="category tag">Others</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <div class="post" id="post-7115300"> <h2><a class="title" href="http://www.webmastersgallery.com/2024/09/13/two-css-properties-for-trimming-text-box-whitespace/" rel="bookmark">Two CSS Properties for Trimming Text Box Whitespace</a></h2> <div class="info"> <span class="date">September 13th, 2024</span> <span class="author"><a href="http://www.webmastersgallery.com/author/admin/" title="Posts by admin" rel="author">admin</a></span> <span class="comments"><a href="http://www.webmastersgallery.com/2024/09/13/two-css-properties-for-trimming-text-box-whitespace/#respond">No comments</a></span> <div class="fixed"></div> </div> <div class="content"> <div class="ftpimagefix" style="float:left"><a target="_blank" href="1" rel="noopener"><img decoding="async" data-recalc-dims="1" loading="lazy" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/s_E1E080058CE547E0AE943D73C95F1DDF6B532B7E5B1E24BDE98684D14ED96D2D_1725557153250_1.png?resize=2880%2C1800&ssl=1" alt="The word incendiary showing its text box and whitespace above and below it." class="wp-image-380795"></a></div> <p>The <code><strong>text-box-trim</strong></code> and <code><strong>text-box-edge</strong></code> properties in CSS enable developers to trim specifiable amounts of the whitespace that appear above the first formatted line of text and below the last formatted line of text in a text box, making the text box vertically larger than the content within.</p> <p>This whitespace is called <strong>leading</strong>, and it appears above and below (so it’s two half-leadings, actually) all lines of text to make the text more readable. However, we only want it to appear <i>in between</i> lines of text, right? We don’t want it to appear along the over or under edges of our text boxes, because then it interferes with our margins, paddings, gaps, and other spacings.</p> <p><span></span></p> <p>As an example, if we implement a <code>50px</code> margin but then the leading adds another <code>37px</code>, we’d end up with a grand total of <code>87px</code> of space. Then we’d need to adjust the margin to <code>13px</code> in order to make the space <code>50px</code> in practice.</p> <figure class="wp-block-image size-full"></figure> <p>As a design systems person, I try to maintain as much consistency as possible and use very little markup whenever possible, which enables me to use the <a target="_blank" href="https://css-tricks.com/css-selectors/#aa-adjacent-combinator" rel="noreferrer noopener">adjacent-sibling combinator</a> (<code>+</code>) to create blanket rules like this:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>/* Whenever <element> is followed by <h1> */ <element> + h1 { margin-bottom: 13px; /* instead of margin-bottom: 50px; */ }</code></pre> <p>This approach is still a headache since you still have to do the math (albeit less of it). But with the <code>text-box-trim</code> and <code>text-box-edge</code> properties, <code>50px</code> as defined by CSS will mean <code>50px</code> visually:</p> <figure class="wp-block-image size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="2880" height="1800" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/s_E1E080058CE547E0AE943D73C95F1DDF6B532B7E5B1E24BDE98684D14ED96D2D_1725557345406_2.png?resize=2880%2C1800&ssl=1" alt="The word incendiary with its text box flush against its top and bottom edges." class="wp-image-380796"></figure> <p class="is-style-explanation"><strong>Disclaimer:</strong> <code>text-box-trim</code> and<code> text-box-edge</code> are only accessible via a feature flag in Chrome 128+ and Safari 16.4+, as well as Safari Technology Preview without a feature flag. See <a target="_blank" href="https://caniuse.com/css-text-box-trim" rel="noreferrer noopener">Caniuse</a> for the latest browser support.</p> <h3 class="wp-block-heading">Start with <code>text-box-trim</code><br /> </h3> <p>text-box-trim is the CSS property that basically activates text box trimming. It doesn’t really have a use beyond that, but it does provide us with the option to trim from just the start, just the end, both the start and end, or <code>none</code>:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-trim: trim-start; text-box-trim: trim-end; text-box-trim: trim-both; text-box-trim: none;</code></pre> <p class="is-style-explanation"><strong>Note:</strong> In older web browsers, you might need to use the older <code>start</code>/<code>end</code>/<code>both</code> values in place of the newer <code>trim-start</code>/<code>trim-end</code>/<code>trim-both</code> values, respectively. In even older web browsers, you might need to use <code>top</code>/<code>bottom</code>/<code>both</code>. There’s no reference for this, unfortunately, so you’ll just have to see what works.</p> <h3 class="wp-block-heading">Now, where do you want to trim from?</h3> <p>You’re probably wondering what I mean by that. Well, consider that a typographic letter has multiple peaks.</p> <p>There’s the x-height, which marks the top of the letter “x” and other lowercase characters (not including <a target="_blank" href="https://fonts.google.com/knowledge/glossary/ascenders_descenders" rel="noreferrer noopener">ascenders</a> or <a target="_blank" href="https://fonts.google.com/knowledge/glossary/overshoot" rel="noreferrer noopener">overshoots</a>), the cap height, which marks the top of uppercase characters (again, not including ascenders or overshoots), and the alphabetic baseline, which marks the <em>bottom</em> of most letters (not including <a target="_blank" href="https://fonts.google.com/knowledge/glossary/ascenders_descenders" rel="noreferrer noopener"><em>descenders</em></a> or overshoots). Then of course there’s the ascender height and descender height too.</p> <p>You can trim the whitespace between the x-height, cap height, or ascender height and the “over” edge of the text box (this is where overlines begin), and also the white space between the alphabetic baseline or descender height and the “under” edge (where underlines begin if <code>text-underline-position</code> is set to <code>under</code>).</p> <h4 class="wp-block-heading">Don’t trim anything</h4> <p><code>text-box-edge: leading</code> means to include all of the leading; simply don’t trim anything. This has the same effect as <code>text-box-trim: none</code> or forgoing <code>text-box-trim</code> and <code>text-box-edge</code> entirely. You could also restrict under-edge trimming with text-box-trim: trim-start or over edge trimming with <code>text-box-trim: trim-end</code>. Yep, there are quite a few ways to not even do this thing at all!</p> <p>Newer web browsers have deviated from the CSSWG specification working drafts by removing the <code>leading</code> value and replacing it with <code>auto</code>, despite the “Do not ship (yet)” warning (*shrug*).</p> <p>Naturally, <code>text-box-edge</code> accepts two values (an instruction regarding the over edge, then an instruction regarding the under edge). However, <code>auto</code> must be used solo.</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-edge: auto; /* Works */ text-box-edge: ex auto; /* Doesn't work */ text-box-edge: auto alphabetic; /* Doesn't work */</code></pre> <p>I could explain all the scenarios in which auto would work, but none of them are useful. I think all we want from <code>auto</code> is to be able to set the over or under edge to auto and the other edge to something else, but this is the only thing that it doesn’t do. This is a problem, but we’ll dive into that shortly. </p> <h4 class="wp-block-heading">Trim above the ascenders and/or below the descenders</h4> <p>The <code>text</code> value will trim above the ascenders if used as the first value and below the descenders if used as the second value and is also the default value if you fail to declare the second value. (I think you’d want it to be <code>auto</code>, but it won’t be.)</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-edge: ex text; /* Valid */ text-box-edge: ex; /* Computed as `text-box-edge: ex text;` */ text-box-edge: text alphabetic; /* Valid */ text-box-edge: text text; /* Valid */ text-box-edge: text; /* Computed as `text-box-edge: text text;` */</code></pre> <p>It’s worth noting that ascender and descender height metrics come from the fonts themselves (or not!), so text can be quite finicky. For example, with the Arial font, the ascender height includes diacritics and the descender height includes descenders, whereas with the Fraunces font, the descender height includes diacritics and I don’t know what the ascender height includes. For this reason, <a target="_blank" href="https://www.w3.org/TR/css-inline-3/#issue-d656b674" rel="noreferrer noopener">there’s talk</a> about renaming <code>text</code> to <code>from-font</code>.</p> <figure class="wp-block-image size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="2880" height="1800" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/s_E1E080058CE547E0AE943D73C95F1DDF6B532B7E5B1E24BDE98684D14ED96D2D_1725557399804_3.png?resize=2880%2C1800&ssl=1" alt="The word incendiary written in two variations with accents showing how the test box is affected." class="wp-image-380797"></figure> <h2 class="wp-block-heading">Trim above the cap height only</h2> <p>To trim above the cap height:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-edge: cap; /* Computed as text-box-edge: cap text; */</code></pre> <figure class="wp-block-image size-large"><img decoding="async" data-recalc-dims="1" loading="lazy" width="1024" height="640" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/s_E1E080058CE547E0AE943D73C95F1DDF6B532B7E5B1E24BDE98684D14ED96D2D_1725557406433_4.png?resize=1024%2C640&ssl=1" alt="The word incendiary with the D character slightly outside the top of the text box boundary." class="wp-image-380798"></figure> <p>Remember, undeclared values default to text, not auto (as demonstrated above). Therefore, to opt out of trimming the under edge, you’d need to use <code>trim-start instead</code> of <code>trim-both</code>:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-trim: trim-start; /* Not text-box-trim: trim-both; */ text-box-edge: cap; /* Not computed as text-box-edge: cap text; */</code></pre> <h4 class="wp-block-heading">Trim above the cap height and below the alphabetic baseline</h4> <p>To trim above the cap height and below the alphabetic baseline:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-trim: trim-both; text-box-edge: cap alphabetic;</code></pre> <figure class="wp-block-image size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="2880" height="1800" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/s_E1E080058CE547E0AE943D73C95F1DDF6B532B7E5B1E24BDE98684D14ED96D2D_1725557415943_5.png?resize=2880%2C1800&ssl=1" alt="The word incendiary with no whitespace." class="wp-image-380799"></figure> <p>By the way, the “Cap height to baseline” option of Figma’s “Vertical trim” setting does exactly this. However, its Dev Mode produces CSS code with outdated property names (<code>leading-trim</code> and <code>text-edge</code>) and outdated values (<code>top</code> and <code>bottom</code>).</p> <figure class="wp-block-image size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="2880" height="1800" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/s_E1E080058CE547E0AE943D73C95F1DDF6B532B7E5B1E24BDE98684D14ED96D2D_1725653194245_Screenshot2024-09-06at21.06.02.png?resize=2880%2C1800&ssl=1" alt="Figma screenshot of text settings." class="wp-image-380800"></figure> <h4 class="wp-block-heading">Trim above the x-height only</h4> <p>To trim above the x-height only:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-trim: trim-start; text-box-edge: ex;</code></pre> <figure class="wp-block-image size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="2880" height="1800" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/s_E1E080058CE547E0AE943D73C95F1DDF6B532B7E5B1E24BDE98684D14ED96D2D_1725557421943_6.png?resize=2880%2C1800&ssl=1" alt="The word incendiary with slight spacing along the bottom edge of its text box." class="wp-image-380801"></figure> <h2 class="wp-block-heading">Trim above the x-height and below the alphabetic baseline</h2> <p>To trim above the x-height and below the alphabetic baseline:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-trim: trim-both; text-box-edge: ex alphabetic;</code></pre> <figure class="wp-block-image size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="2880" height="1800" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/s_E1E080058CE547E0AE943D73C95F1DDF6B532B7E5B1E24BDE98684D14ED96D2D_1725557450554_7.png?resize=2880%2C1800&ssl=1" alt="The word incendiary with no whitespace." class="wp-image-380802"></figure> <h2 class="wp-block-heading">Trim below the alphabetic baseline only</h2> <p>To trim below the alphabetic baseline only, the following <strong>won’t</strong> work (things were going so well for a moment, weren’t they?):</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-trim: trim-end; text-box-edge: alphabetic;</code></pre> <p>This is because the first value is always the mandatory over-edge value whereas the second value is an optional under-edge value. This means that alphabetic isn’t a valid over-edge value, even though the inclusion of <code>trim-end</code> suggests that we won’t be providing one. Complaints about verbosity aside, the correct syntax would have you declare any over-edge value even though you’d effectively cancel it out with <code>trim-end</code>:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-trim: trim-end; text-box-edge: [any over edge value] alphabetic;</code></pre> <figure class="wp-block-image size-full"><img decoding="async" data-recalc-dims="1" loading="lazy" width="2880" height="1800" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/s_E1E080058CE547E0AE943D73C95F1DDF6B532B7E5B1E24BDE98684D14ED96D2D_1725557472660_8.png?resize=2880%2C1800&ssl=1" alt="The word incendiary with slight whitespace along the upper edge of its text box." class="wp-image-380803"></figure> <h3 class="wp-block-heading">What about ideographic glyphs?</h3> <p>It’s difficult to know how web browsers will trim ideographic glyphs until they do, but you can read all about it in <a target="_blank" href="https://www.w3.org/TR/css-inline-3/#propdef-text-box-edge" rel="noreferrer noopener">the spec</a>. In theory, you’d want to use the <code>ideographic-ink</code> value for trimming and the <code>ideographic</code> value for no trimming, both of which aren’t unsupported yet:</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>text-box-edge: ideographic; /* No trim */ text-box-edge: ideographic-ink; /* Trim */ text-box-edge: ideographic-ink ideographic; /* Top trim */ text-box-edge: ideographic ideographic-ink; /* Bottom trim */</code></pre> <h3 class="wp-block-heading"> <code>text-box</code>, the shorthand property</h3> <p>If you’re not keen on the verbosity of text box trimming, there’s a shorthand <code>text-box</code> property that makes it somewhat inconsequential. All the same rules apply.</p> <pre class="wp-block-csstricks-code-block language-css" data-line=""><code>/* Syntax */ text-box: [text-box-trim] [text-box-edge (over)] [text-box-edge (under)]? /* Example */ text-box: trim-both cap alphabetic;</code></pre> <h3 class="wp-block-heading">Final thoughts</h3> <p>At first glance, <code>text-box-trim</code> and <code>text-box-edge</code> might not seem all that interesting, but they do make spacing elements a heck of a lot simpler.</p> <p>Is the current proposal the best way to handle text box trimming though? Personally, I don’t think so. I think <code>text-box-trim-start</code> and <code>text-box-trim-end</code> would make a lot more sense, with <code>text-box-trim</code> being used as the shorthand property and <code>text-box-edge</code> not being used at all, but I’d settle for some simplification and/or consistent practices. What do you think?</p> <p>There are some other concerns too. For example, <a target="_blank" href="https://drafts.csswg.org/css-inline-3/#issue-8de59d00" rel="noreferrer noopener">should there be an option to include underlines, overlines, hanging punctuation marks, or diacritics?</a> I’m going to say yes, especially if you’re using <code>text-underline-position: under</code> or a particularly thick <code>text-decoration-thickness</code>, as they can make the spacing between elements appear smaller.</p> </p> <hr> <p><small><a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/two-css-properties-for-trimming-text-box-whitespace/">Two CSS Properties for Trimming Text Box Whitespace</a> originally published on <a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/">CSS-Tricks</a>, which is part of the <a target="_blank" href="https://try.digitalocean.com/css-tricks/?utm_medium=rss&utm_source=css-tricks.com&utm_campaign=family_&utm_content=" rel="noopener">DigitalOcean</a> family. You should <a target="_blank" href="https://css-tricks.com/newsletters/" rel="noopener">get the newsletter</a>.</small></p> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://www.webmastersgallery.com/category/design/" rel="category tag">Designing</a>, <a href="http://www.webmastersgallery.com/category/uncategorized/" rel="category tag">Others</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <div class="post" id="post-7113377"> <h2><a class="title" href="http://www.webmastersgallery.com/2024/09/12/whats-old-is-new-2/" rel="bookmark">What’s Old is New</a></h2> <div class="info"> <span class="date">September 12th, 2024</span> <span class="author"><a href="http://www.webmastersgallery.com/author/admin/" title="Posts by admin" rel="author">admin</a></span> <span class="comments"><a href="http://www.webmastersgallery.com/2024/09/12/whats-old-is-new-2/#respond">No comments</a></span> <div class="fixed"></div> </div> <div class="content"> <p>I collect a bunch of links in a bookmarks folder. These are things I fully intend to read, and I do — eventually. It’s a good thing bookmarks are digital, otherwise, I’d need a bigger coffee table to separate them from the ever-growing pile of magazines.</p> <p>The benefit of accumulating links is that the virtual pile starts revealing recurring themes. Two seemingly unrelated posts published a couple months apart may congeal and become more of a dialogue around a common topic.</p> <p>I spent time pouring through a pile of links I’d accumulated over the past few weeks and noticed a couple of trending topics. No, that’s not me you’re smelling — there’s an aroma of nostalgia in the air., namely a newfound focus on learning web fundamentals and some love for manual deployments.</p> <p><span></span></p> <h3 class="wp-block-heading">Web Developers, AI, and Development Fundamentals</h3> <p><a target="_blank" href="https://alvaromontoro.com/blog/68061/web-developers-ai-development-fundamentals" rel="noopener">Alvaro Montero</a>:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>Ultimately, <strong>it is not about AI replacing developers, but about developers adapting and evolving with the tools</strong>. The ability to learn, understand, and apply the fundamentals is essential because tools will only take you so far without the proper foundation.</p> </blockquote> <h3 class="wp-block-heading">ShopTalk 629: The Great Divide, Global Design + Web Components, and Job Titles</h3> <p>Chris and Dave sound off on <a target="_blank" href="https://css-tricks.com/the-great-divide/" rel="noopener">The Great Divide</a> in <a target="_blank" href="https://shoptalkshow.com/629/" rel="noopener">this episode</a> and the rising value of shifting back towards fundamentals:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p><strong>Dave:</strong> But I think what is maybe missing from that is there was a very big feeling of disenfranchisement from people who are good and awesome at CSS and JavaScript and HTML. But then were being… The market was shifting hard to these all-in JavaScript frameworks. And a lot of people were like, “I don’t… This is not what I signed up for.”</p> <p>[…]</p> <p><strong>Dave:</strong> Yeah. I’m sure you can be like, “Eat shit. That’s how it is, kid.” But that’s also devaluing somebody’s skillset. And I think what the market is proving now is if you know JavaScript or know HTML, CSS, and regular JavaScript (non-framework JavaScript), you are once again more valuable because you understand how a line of CSS can replace 10,000 lines of JavaScript – or whatever it is.</p> <p><strong>Chris:</strong> Yeah. Maybe it’s coming back just a smidge–</p> <p><strong>Dave:</strong> A smidge.</p> <p><strong>Chris:</strong> –that kind of respecting the fundamental stuff because there’s been churn since then, since five years ago. Now it’s like these exclusively React developers we hired, how useful are they anymore? Were they a little too limited and fundamental people are knowing more? I don’t know. It’s hard to say that the job industry is back when it doesn’t quite feel that way to me.</p> <p><strong>Dave:</strong> Yeah, yeah. Yeah, who knows. I just think the value in knowing CSS and HTML, good HTML, are up more than they maybe were five years ago.</p> </blockquote> <h3 class="wp-block-heading">Just a Spec: HTML Finally Gets the Respect It Deserves</h3> <p><a target="_blank" href="https://justaspec.buzzsprout.com/1863126/episodes/15392956-pendulum-swings-2023-s-state-of-js" rel="noopener">Jared and Ayush</a> riffin’ on the first ever State of HTML survey, why we need it, and whether “State of…” surveys are representative of people who work with HTML.</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>[…] once you’ve learned about divs and H’s 1 through 6, what else is there to know? Quite a lot, as it turns out. Once again, we drafted Lea Verou to put her in-depth knowledge of the web platform to work and help us craft a survey that ended up reaching far beyond pure HTML to cover accessibility, web components, and much more.</p> <p>[…]</p> <p>You know, it’s perfectly fine to be an expert at HTML and CSS and know very little JavaScript. So, yeah, I think it’s important to note that as we talk about the survey, because the survey is a snapshot of just the people who know about the survey and answer the questions, right? It’s not necessarily representative of the broad swath of people around the world who have used HTML at all.</p> <p>[…]</p> <p>So yeah, a lot of interest in HTML. I’m talking about HTML. And yeah, in the conclusion, Lea Verou talks about we really do have this big need for more extensibility of HTML.</p> </blockquote> <p>In a more <a target="_blank" href="https://justaspec.buzzsprout.com/1863126/episodes/15392956-pendulum-swings-2023-s-state-of-js" rel="noopener">recent episode</a>:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>I’m not surprised. I mean, when someone who’s only ever used React can see what HTML does, I think it’s usually a huge revelation to them.</p> <p>[…]</p> <p>It just blows their minds. And it’s kind of like you just don’t know what you’re missing out on up to a point. And there is a better world out there that a lot of folks just don’t know about.</p> <p>[…]</p> <p>I remember a while back seeing a post come through on social media somewhere, somebody’s saying, oh, I just tried working with HTML forms, just standard HTML forms the first time and getting it to submit stuff. And wait, it’s that easy?</p> <p>Yeah, last year when I was mentoring a junior developer with the Railsworld conference website, she had come through Bootcamp and only ever done React, and I was showing her what a web component does, and she’s like, oh, man, this is so cool. Yeah, it’s the web platform.</p> </blockquote> <h3 class="wp-block-heading">Reckoning: Part 4 — The Way Out</h3> <p>Alex Russell in <a target="_blank" href="%20Part%204%20%E2%80%94%20The%20Way%20Out" rel="noopener">the last installment</a> of an epic four-part series well worth your time to fully grasp the timeline, impact, and costs of modern JavsaScript frameworks to today’s development practices:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>Never, ever hire for JavaScript framework skills. Instead, interview and hire only for fundamentals like web standards, accessibility, modern CSS, semantic HTML, and Web Components. This is <em>doubly</em> important if your system uses a framework.</p> </blockquote> <h3 class="wp-block-heading">Semi-Annual Reminder to Learn and Hire for Web Standards</h3> <p><a target="_blank" href="https://adrianroselli.com/2024/09/semi-annual-reminder-to-learn-and-hire-for-web-standards.html" rel="noopener">Adrian Roselli</a>:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>This is a common cycle. Web developers tire of a particular technology — often considered the HTML killer when released — and come out of it calling for a focus on the native web platform. Then they decide to reinvent it yet again, but poorly.</p> <p>There are many reasons companies won’t make deep HTML / CSS / ARIA / SVG knowledge core requirements. The simplest is the commoditization of the skills, partly because framework and library developers have looked down on the basics.</p> </blockquote> <h3 class="wp-block-heading">The anchor element</h3> <p><a target="_blank" href="https://heydonworks.com/article/the-anchor-element/" rel="noopener">Heydon Pickering</a> in a series dedicated to HTML elements, starting alphabetically with the good ol’ anchor <code><a></code>:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>Sometimes, the <code><a></code> is referred to as a hyperlink, or simply a <em>link</em>. But it is not one of these and people who say it is one are technically wrong (the worst kind of wrong).</p> <p>[…]</p> <p>Web developers and content editors, the world over, make the mistake of <strong>not making text that describes a link actually go inside that link</strong>. This is collosally unfortunate, given it’s the main thing to get right when writing <em>hypertext</em>.</p> </blockquote> <h3 class="wp-block-heading">AI Myth: It lets me write code I can’t on my own</h3> <p><a target="_blank" href="https://gomakethings.com/ai-myth-it-lets-me-write-code-i-cant-on-my-own/" rel="noopener">Chris Ferndandi</a>:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>At the risk of being old and out-of-touch: if you don’t know how to write some code, you probably shouldn’t use code that Chat GPT et al write for you.</p> <p>[…]</p> <p>It’s not bulletproof, but StackOverflow provides opportunities to learn and <em>understand the code</em> in a way that AI-generated code does not.</p> </blockquote> <h3 class="wp-block-heading">What Skills Should You Focus on as Junior Web Developer in 2024?</h3> <p><a target="_blank" href="https://frontendmasters.com/blog/what-skills-should-you-focus-on-as-junior-web-developer-in-2024/" rel="noopener">Frontend Masters:</a></p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>Let’s not be <code>old-man-shakes-fist-at-kids.gif</code> about this, but learning the fundamentals of tech is demonstrateably useful. It’s true in basketball, it’s true for the piano, and it’s true in making websites. If you’re aiming at a long career in websites, the fundamentals are what powers it.</p> <p>[…]</p> <p>The point of the fundamentals is how long-lasting and transferrable the knowledge is. It will serve you well no matter what <em>other</em> technologies a job might have you using, or when the abstractions over them change, as they are want to do.</p> </blockquote> <p>As long as we’re talking about learning the fundamentals…</p> <h3 class="wp-block-heading">The Basics</h3> <p>Oh yeah, and of course there’s this little <a target="_blank" href="https://thebasics.dev/" rel="noopener">online course</a> I released this summer for learning HTML and CSS fundamentals that I <a target="_blank" href="https://geoffgraham.me/the-basics-dev/" rel="noopener">describe</a> like this:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>The Basics is more for your clients who do not know how to update the website they paid you to make. Or the friend who’s learning but still keeps bugging you with questions about the things they’re reading. Or your mom, who still has no idea what it is you do for a living. It’s for those whom the entry points are vanishing. It’s for those who could simply sign up for a Squarespace account but want to understand the code it spits out so they have more control to make a site that uniquely reflects them.</p> </blockquote> <p>Not all this nostalgia is reserved only for HTML and CSS, but for deploying code, too. A few recent posts riff on what it might look like to ship code with “buildless” or <em>near</em> “buildless” workflows.</p> <h3 class="wp-block-heading">Raw-Dogging Websites</h3> <p><a target="_blank" href="https://bradfrost.com/blog/post/raw-dogging-websites/" rel="noopener">Brad Frost</a>:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>It is extraordinarily liberating. Yes, there are some ergonomic inefficiencies, but at the end of the day it comes out in the wash. You might have to copy-and-paste some HTML, but in my experience I’d spend that much time or more debugging a broken build or dependency hell.</p> </blockquote> <h3 class="wp-block-heading">Going Buildless</h3> <p><a target="_blank" href="https://mxb.dev/blog/buildless/" rel="noopener">Max Böck</a> in a follow-up to Brad:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>So, can we all ditch our build tools soon?</p> <p>Probably not. I’d say for production-grade development, we’re not quite there yet. Performance tradeoffs are a big part of it, but there are lots of other small problems that you’d likely run into pretty soon once you hit a certain level of complexity.</p> <p>For smaller sites or side projects though, I can imagine going the buildless route – just to see how far I can take it.</p> </blockquote> <h3 class="wp-block-heading">Manual ’till it hurts</h3> <p><a target="_blank" href="https://adactio.com/journal/21397" rel="noopener">Jeremy Keith</a> in a follow-up to Max:</p> <blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"> <p>If you’re thinking that your next project couldn’t possibly be made without a build step, let me tell you about a phrase I first heard in the <a target="_blank" href="https://indieweb.org/" rel="noopener">indie web</a> community: “Manual ‘till it hurts”. It’s basically a two-step process:</p> </p> <ol class="wp-block-list"> <li>Start doing what you need to do by hand.</li> <li>When that becomes unworkable, introduce some kind of automation.</li> </ol> <p>It’s remarkable how often you never reach step two.</p> <p>I’m not saying premature optimisation is the root of all evil. I’m just saying it’s premature.</p> </blockquote> <hr class="wp-block-separator has-alpha-channel-opacity"> <p>That’s it for this pile of links and good gosh my laptop feels lighter for it. Have you read other recent posts that tread similar ground? Share ’em in the comments.</p> <hr> <p><small><a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/whats-old-is-new-2/">What’s Old is New</a> originally published on <a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/">CSS-Tricks</a>, which is part of the <a target="_blank" href="https://try.digitalocean.com/css-tricks/?utm_medium=rss&utm_source=css-tricks.com&utm_campaign=family_&utm_content=" rel="noopener">DigitalOcean</a> family. You should <a target="_blank" href="https://css-tricks.com/newsletters/" rel="noopener">get the newsletter</a>.</small></p> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://www.webmastersgallery.com/category/design/" rel="category tag">Designing</a>, <a href="http://www.webmastersgallery.com/category/uncategorized/" rel="category tag">Others</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <div class="post" id="post-7109843"> <h2><a class="title" href="http://www.webmastersgallery.com/2024/09/10/quick-hit-18/" rel="bookmark">Quick Hit #18</a></h2> <div class="info"> <span class="date">September 10th, 2024</span> <span class="author"><a href="http://www.webmastersgallery.com/author/admin/" title="Posts by admin" rel="author">admin</a></span> <span class="comments"><a href="http://www.webmastersgallery.com/2024/09/10/quick-hit-18/#respond">No comments</a></span> <div class="fixed"></div> </div> <div class="content"> <p><strong>PSA:</strong> Today’s the day that Google’s performance tools officially <a target="_blank" href="https://web.dev/blog/fid?hl=en" rel="noopener">stops supporting</a> the First Input Delay (FID) metric that was replaced by Interaction to Next Paint (INP).</p> <hr> <p><small><a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/quick-hit-18/">Quick Hit #18</a> originally published on <a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/">CSS-Tricks</a>, which is part of the <a target="_blank" href="https://try.digitalocean.com/css-tricks/?utm_medium=rss&utm_source=css-tricks.com&utm_campaign=family_&utm_content=" rel="noopener">DigitalOcean</a> family. You should <a target="_blank" href="https://css-tricks.com/newsletters/" rel="noopener">get the newsletter</a>.</small></p> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://www.webmastersgallery.com/category/design/" rel="category tag">Designing</a>, <a href="http://www.webmastersgallery.com/category/uncategorized/" rel="category tag">Others</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <div class="post" id="post-7109924"> <h2><a class="title" href="http://www.webmastersgallery.com/2024/09/10/sanding-ui/" rel="bookmark">Sanding UI</a></h2> <div class="info"> <span class="date">September 10th, 2024</span> <span class="author"><a href="http://www.webmastersgallery.com/author/admin/" title="Posts by admin" rel="author">admin</a></span> <span class="comments"><a href="http://www.webmastersgallery.com/2024/09/10/sanding-ui/#respond">No comments</a></span> <div class="fixed"></div> </div> <div class="content"> <div class="ftpimagefix" style="float:left"><a target="_blank" href="1" rel="noopener"><img decoding="async" loading="lazy" src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2024/09/radios-flexbox-animated.gif?resize=344%2C270&ssl=1" alt="" class="wp-image-380663" data-recalc-dims="1"></a></div> <p>Jim hit a snag while working on a form. Placing labels next to inputs is trivial with flexbox, sure, but what happened in Jim’s case was a bit of dead-clicking between the labels and radio buttons.</p> <p><span></span></p> <figure class="wp-block-image size-full is-resized"></figure> <p>The issue? Not the markup, that’s all semantic and cool. Turns out the <code>gap</code> he placed between the elements is non-interactive. Makes sense when you think about it, but frustrating nonetheless because it looks like a bug and feels like a bug even though there’s nothing wrong with the styles.</p> <p>The solution’s easy enough: padding along the inside edge of the input extends its box dimensions, allowing the added space to remain interactive with visual spacing. Margin wouldn’t work since it’s akin to <code>gap</code> in that it pushes the element’s box instead of expanding it.</p> <p>I’m linking up Jim’s article because it’s a perfect demonstration that CSS is capable of accomplishing <a target="_blank" href="https://css-tricks.com/hearts-in-html-and-css/" rel="noopener">the same thing in many ways</a>. It’s easy to fall into the trap of “single-solution” thinking, but CSS doesn’t want anything to do with that. It’ll instead challenge you to adapt toward open-minded strategies, perhaps even <a target="_blank" href="https://defensivecss.dev/" rel="noopener">defensive ones</a>.</p> <hr> <p><small><a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/sanding-ui/">Sanding UI</a> originally published on <a target="_blank" rel="nofollow noopener" href="https://css-tricks.com/">CSS-Tricks</a>, which is part of the <a target="_blank" href="https://try.digitalocean.com/css-tricks/?utm_medium=rss&utm_source=css-tricks.com&utm_campaign=family_&utm_content=" rel="noopener">DigitalOcean</a> family. You should <a target="_blank" href="https://css-tricks.com/newsletters/" rel="noopener">get the newsletter</a>.</small></p> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://www.webmastersgallery.com/category/design/" rel="category tag">Designing</a>, <a href="http://www.webmastersgallery.com/category/uncategorized/" rel="category tag">Others</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <div id="pagenavi"> <span class="newer"></span> <span class="older"><a href="http://www.webmastersgallery.com/2024/09/0/page/2/" >Older Entries</a></span> <div class="fixed"></div> </div> </div> <!-- main END --> <!-- sidebar START --> <div id="sidebar"> <!-- sidebar north START --> <div id="northsidebar" class="sidebar"> <!-- feeds --> <div class="widget widget_feeds"> <div class="content"> <div id="subscribe"> <a rel="external nofollow" id="feedrss" title="Subscribe to this blog..." href="http://www.webmastersgallery.com/feed/"><abbr title="Really Simple Syndication">RSS</abbr></a> </div> <div class="fixed"></div> </div> </div> <!-- showcase --> <div id="text-389627311" class="widget widget_text"> <div class="textwidget"><a href="http://feeds2.feedburner.com/webmastersgallery" title="Subscribe to my feed" rel="alternate" type="application/rss+xml"><img src="http://www.feedburner.com/fb/images/pub/feed-icon32x32.png" alt="" style="border:0"/></a><a href="http://feeds2.feedburner.com/webmastersgallery" title="Subscribe to my feed" rel="alternate" type="application/rss+xml">Subscribe for latest Updates</a></div> </div><div id="text-389629461" class="widget widget_text"> <div class="textwidget"><form style="border:1px solid #ccc;padding:3px;text-align:center;" action="http://feedburner.google.com/fb/a/mailverify" method="post" target="popupwindow" onsubmit="window.open('http://feedburner.google.com/fb/a/mailverify?uri=webmastersgallery', 'popupwindow', 'scrollbars=yes,width=550,height=520');return true"><p>Enter your email address:</p><p><input type="text" style="width:140px" name="email"/></p><input type="hidden" value="webmastersgallery" name="uri"/><input type="hidden" name="loc" value="en_US"/><input type="submit" value="Subscribe" /><p>Delivered by <a href="http://feedburner.google.com" target="_blank" rel="noopener">FeedBurner</a></p></form></div> </div></div> <!-- sidebar north END --> <div id="centersidebar"> <!-- sidebar east START --> <div id="eastsidebar" class="sidebar"> <!-- categories --> <div class="widget widget_categories"> <h3>Categories</h3> <ul> <li class="cat-item cat-item-518"><a href="http://www.webmastersgallery.com/category/affiliate-programs/">Affiliate Programs</a> </li> <li class="cat-item cat-item-147"><a href="http://www.webmastersgallery.com/category/design/">Designing</a> </li> <li class="cat-item cat-item-519"><a href="http://www.webmastersgallery.com/category/domain-names/">Domain Names</a> </li> <li class="cat-item cat-item-37"><a href="http://www.webmastersgallery.com/category/e-commerce/">E-commerce</a> </li> <li class="cat-item cat-item-509"><a href="http://www.webmastersgallery.com/category/internet-directories/">Internet Directories</a> </li> <li class="cat-item cat-item-510"><a href="http://www.webmastersgallery.com/category/message-boards/">Message Boards</a> </li> <li class="cat-item cat-item-1"><a href="http://www.webmastersgallery.com/category/uncategorized/">Others</a> </li> <li class="cat-item cat-item-506"><a href="http://www.webmastersgallery.com/category/programming/">Programming</a> </li> <li class="cat-item cat-item-511"><a href="http://www.webmastersgallery.com/category/promotion-and-marketing/">Promotion and Marketing</a> </li> <li class="cat-item cat-item-534"><a href="http://www.webmastersgallery.com/category/scripts-and-programming/">Scripts and Programming</a> </li> <li class="cat-item cat-item-513"><a href="http://www.webmastersgallery.com/category/search-engines/">Search Engines</a> </li> <li class="cat-item cat-item-135"><a href="http://www.webmastersgallery.com/category/social-media/">Social Media</a> </li> <li class="cat-item cat-item-514"><a href="http://www.webmastersgallery.com/category/softwares/">Softwares</a> </li> <li class="cat-item cat-item-515"><a href="http://www.webmastersgallery.com/category/tips-and-tutorials/">Tips and Tutorials</a> </li> <li class="cat-item cat-item-338"><a href="http://www.webmastersgallery.com/category/web-hosting/">Web Hosting</a> </li> <li class="cat-item cat-item-516"><a href="http://www.webmastersgallery.com/category/webmaster-tools/">Webmaster Tools</a> </li> <li class="cat-item cat-item-501"><a href="http://www.webmastersgallery.com/category/webmaster-resources/">Webmasters Resources</a> </li> <li class="cat-item cat-item-3"><a href="http://www.webmastersgallery.com/category/web-design/">Website Design</a> </li> </ul> </div> </div> <!-- sidebar east END --> <!-- sidebar west START --> <div id="westsidebar" class="sidebar"> <!-- blogroll --> <div class="widget widget_links"> <h3>Blogroll</h3> <ul> <li><a href="http://wordpress.org/development/">Development Blog</a></li> <li><a href="http://codex.wordpress.org/">Documentation</a></li> <li><a href="http://wordpress.org/extend/plugins/">Plugins</a></li> <li><a href="http://wordpress.org/extend/ideas/">Suggest Ideas</a></li> <li><a href="http://wordpress.org/support/">Support Forum</a></li> <li><a href="http://wordpress.org/extend/themes/">Themes</a></li> <li><a href="http://planet.wordpress.org/">WordPress Planet</a></li> </ul> </div> </div> <!-- sidebar west END --> <div class="fixed"></div> </div> <!-- sidebar south START --> <div id="southsidebar" class="sidebar"> <!-- archives --> <div class="widget"> <h3>Archives</h3> <ul> <li><a href='http://www.webmastersgallery.com/2024/09/' aria-current="page">September 2024</a></li> <li><a href='http://www.webmastersgallery.com/2024/08/'>August 2024</a></li> <li><a href='http://www.webmastersgallery.com/2024/07/'>July 2024</a></li> <li><a href='http://www.webmastersgallery.com/2024/06/'>June 2024</a></li> <li><a href='http://www.webmastersgallery.com/2024/05/'>May 2024</a></li> <li><a href='http://www.webmastersgallery.com/2024/04/'>April 2024</a></li> <li><a href='http://www.webmastersgallery.com/2024/03/'>March 2024</a></li> <li><a href='http://www.webmastersgallery.com/2024/02/'>February 2024</a></li> <li><a href='http://www.webmastersgallery.com/2024/01/'>January 2024</a></li> <li><a href='http://www.webmastersgallery.com/2023/12/'>December 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/11/'>November 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/10/'>October 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/09/'>September 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/08/'>August 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/07/'>July 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/06/'>June 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/05/'>May 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/04/'>April 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/03/'>March 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/02/'>February 2023</a></li> <li><a href='http://www.webmastersgallery.com/2023/01/'>January 2023</a></li> <li><a href='http://www.webmastersgallery.com/2022/12/'>December 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/11/'>November 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/10/'>October 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/09/'>September 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/08/'>August 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/07/'>July 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/06/'>June 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/05/'>May 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/04/'>April 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/03/'>March 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/02/'>February 2022</a></li> <li><a href='http://www.webmastersgallery.com/2022/01/'>January 2022</a></li> <li><a href='http://www.webmastersgallery.com/2021/12/'>December 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/11/'>November 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/10/'>October 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/09/'>September 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/08/'>August 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/07/'>July 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/06/'>June 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/05/'>May 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/04/'>April 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/03/'>March 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/02/'>February 2021</a></li> <li><a href='http://www.webmastersgallery.com/2021/01/'>January 2021</a></li> <li><a href='http://www.webmastersgallery.com/2020/12/'>December 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/11/'>November 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/10/'>October 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/09/'>September 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/08/'>August 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/07/'>July 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/06/'>June 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/05/'>May 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/04/'>April 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/03/'>March 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/02/'>February 2020</a></li> <li><a href='http://www.webmastersgallery.com/2020/01/'>January 2020</a></li> <li><a href='http://www.webmastersgallery.com/2019/12/'>December 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/11/'>November 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/10/'>October 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/09/'>September 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/08/'>August 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/07/'>July 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/06/'>June 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/05/'>May 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/04/'>April 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/03/'>March 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/02/'>February 2019</a></li> <li><a href='http://www.webmastersgallery.com/2019/01/'>January 2019</a></li> <li><a href='http://www.webmastersgallery.com/2018/12/'>December 2018</a></li> <li><a href='http://www.webmastersgallery.com/2018/11/'>November 2018</a></li> <li><a href='http://www.webmastersgallery.com/2018/10/'>October 2018</a></li> <li><a href='http://www.webmastersgallery.com/2018/09/'>September 2018</a></li> <li><a href='http://www.webmastersgallery.com/2018/08/'>August 2018</a></li> <li><a href='http://www.webmastersgallery.com/2018/07/'>July 2018</a></li> <li><a href='http://www.webmastersgallery.com/2018/04/'>April 2018</a></li> <li><a href='http://www.webmastersgallery.com/2018/01/'>January 2018</a></li> <li><a href='http://www.webmastersgallery.com/2017/12/'>December 2017</a></li> <li><a href='http://www.webmastersgallery.com/2017/11/'>November 2017</a></li> <li><a href='http://www.webmastersgallery.com/2017/09/'>September 2017</a></li> <li><a href='http://www.webmastersgallery.com/2017/08/'>August 2017</a></li> <li><a href='http://www.webmastersgallery.com/2017/07/'>July 2017</a></li> <li><a href='http://www.webmastersgallery.com/2017/06/'>June 2017</a></li> <li><a href='http://www.webmastersgallery.com/2017/05/'>May 2017</a></li> <li><a href='http://www.webmastersgallery.com/2017/04/'>April 2017</a></li> <li><a href='http://www.webmastersgallery.com/2017/03/'>March 2017</a></li> <li><a href='http://www.webmastersgallery.com/2017/02/'>February 2017</a></li> <li><a href='http://www.webmastersgallery.com/2017/01/'>January 2017</a></li> <li><a href='http://www.webmastersgallery.com/2016/12/'>December 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/11/'>November 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/10/'>October 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/09/'>September 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/08/'>August 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/07/'>July 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/06/'>June 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/05/'>May 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/04/'>April 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/03/'>March 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/02/'>February 2016</a></li> <li><a href='http://www.webmastersgallery.com/2016/01/'>January 2016</a></li> <li><a href='http://www.webmastersgallery.com/2015/12/'>December 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/11/'>November 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/10/'>October 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/09/'>September 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/08/'>August 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/07/'>July 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/06/'>June 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/05/'>May 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/04/'>April 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/03/'>March 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/02/'>February 2015</a></li> <li><a href='http://www.webmastersgallery.com/2015/01/'>January 2015</a></li> <li><a href='http://www.webmastersgallery.com/2014/12/'>December 2014</a></li> <li><a href='http://www.webmastersgallery.com/2014/11/'>November 2014</a></li> <li><a href='http://www.webmastersgallery.com/2014/10/'>October 2014</a></li> <li><a href='http://www.webmastersgallery.com/2014/09/'>September 2014</a></li> <li><a href='http://www.webmastersgallery.com/2014/08/'>August 2014</a></li> <li><a href='http://www.webmastersgallery.com/2014/07/'>July 2014</a></li> <li><a href='http://www.webmastersgallery.com/2014/06/'>June 2014</a></li> <li><a href='http://www.webmastersgallery.com/2013/07/'>July 2013</a></li> <li><a href='http://www.webmastersgallery.com/2013/01/'>January 2013</a></li> <li><a href='http://www.webmastersgallery.com/2012/12/'>December 2012</a></li> <li><a href='http://www.webmastersgallery.com/2012/08/'>August 2012</a></li> <li><a href='http://www.webmastersgallery.com/2012/07/'>July 2012</a></li> <li><a href='http://www.webmastersgallery.com/2012/06/'>June 2012</a></li> <li><a href='http://www.webmastersgallery.com/2012/05/'>May 2012</a></li> <li><a href='http://www.webmastersgallery.com/2012/04/'>April 2012</a></li> <li><a href='http://www.webmastersgallery.com/2012/01/'>January 2012</a></li> <li><a href='http://www.webmastersgallery.com/2011/11/'>November 2011</a></li> <li><a href='http://www.webmastersgallery.com/2011/06/'>June 2011</a></li> <li><a href='http://www.webmastersgallery.com/2011/03/'>March 2011</a></li> <li><a href='http://www.webmastersgallery.com/2011/02/'>February 2011</a></li> <li><a href='http://www.webmastersgallery.com/2011/01/'>January 2011</a></li> <li><a href='http://www.webmastersgallery.com/2010/12/'>December 2010</a></li> <li><a href='http://www.webmastersgallery.com/2010/11/'>November 2010</a></li> <li><a href='http://www.webmastersgallery.com/2010/09/'>September 2010</a></li> <li><a href='http://www.webmastersgallery.com/2010/07/'>July 2010</a></li> <li><a href='http://www.webmastersgallery.com/2010/06/'>June 2010</a></li> <li><a href='http://www.webmastersgallery.com/2010/05/'>May 2010</a></li> <li><a href='http://www.webmastersgallery.com/2010/02/'>February 2010</a></li> <li><a href='http://www.webmastersgallery.com/2009/12/'>December 2009</a></li> <li><a href='http://www.webmastersgallery.com/2009/08/'>August 2009</a></li> <li><a href='http://www.webmastersgallery.com/2009/07/'>July 2009</a></li> <li><a href='http://www.webmastersgallery.com/2009/06/'>June 2009</a></li> <li><a href='http://www.webmastersgallery.com/2009/05/'>May 2009</a></li> <li><a href='http://www.webmastersgallery.com/2009/04/'>April 2009</a></li> <li><a href='http://www.webmastersgallery.com/2009/03/'>March 2009</a></li> </ul> </div> <!-- meta --> <div class="widget"> <h3>Meta</h3> <ul> <li><a href="http://www.webmastersgallery.com/wp-login.php">Log in</a></li> </ul> </div> </div> <!-- sidebar south END --> </div> <!-- sidebar END --> <div class="fixed"></div> </div> <!-- content END --> <!-- footer START --> <div id="footer"> <a id="gotop" href="#" onclick="MGJS.goTop();return false;">Top</a> <a id="powered" href="http://wordpress.org/">WordPress</a> <div id="copyright"> Copyright © 2009-2024 Webmasters Gallery </div> <div id="themeinfo"> Theme by <a href="http://www.neoease.com/">NeoEase</a>. Valid <a href="http://validator.w3.org/check?uri=referer">XHTML 1.1</a> and <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS 3</a>. </div> </div> <!-- footer END --> </div> <!-- container END --> </div> <!-- wrap END --> </body> </html>