Tag: Attribute

Mastering SVG’s stroke-miterlimit Attribute

So, SVG has this stroke-miterlimit presentation attribute. You’ve probably seen it when exporting an SVG from a graphic editor program, or perhaps you find out you could remove it without noticing any change to the visual appearance.

After a good amount of research, one of the first things I discovered is that the attribute works alongside stroke-linejoin, and I’ll show you how as well as a bunch of other things I learned about this interesting (and possibly overlooked) SVG attribute.

TLDR;

stroke-miterlimit depends on stroke-linejoin: if we use round or bevel for joins, then there’s no need to declare stroke-miterlimit. But if we use miter instead, we can still delete it and maybe the default value will be enough. Beware that many graphic software editors will add this attribute even when is not necessary.

What is stroke-linejoin?

I know, we’re actually here to talk about stroke-miterlimit, but I want to start with stroke-linejoin because of how tightly they work together. This is the definition for stroke-linejoin pulled straight from the SVG Working Group (SVGWG):

stroke-linejoin specifies the shape to be used at the corners of paths or basic shapes when they are stroked.

This means we can define how the corner looks when two lines meet at a point. And this attribute accepts five possible values, though two of them have no browser implementation and are identified by the spec as at risk of being dropped. So, I’ll briefly present the three supported values the attribute accepts.

miter is the default value and it just so happens to be the most important one of the three we’re looking at. If we don’t explicitly declare stroke-linejoin in the SVG code, then miter is used to shape the corner of a path. We know a join is set to miter when both edges meet at a sharp angle.

But we can also choose round which softens the edges with — you guessed it — rounded corners.

The bevel value, meanwhile, produces a flat edge that sort of looks like a cropped corner.

What is stroke-miterlimit?

OK, now that we know what stroke-linejoin is, let’s get back to the topic at hand and pick apart the definition of stroke-miterlimit from the book Using SVG with CSS3 and HTML5:

[…] on really tight corners, you have to extend the stroke for quite a distance, before the two edges meet. For that reason, there is a secondary property: stroke-miterlimit. It defines how far you can extend the point when creating a miter corner.

In other words, stroke-miterlimit sets how far the stroke of the edges goes before they can meet at a point. And only when the stroke-linejoin is miter.

Miter join with miter limit in grey.

So, the stroke-miterlimit value can be any positive integer, where 4 is the default value. The higher the value, the further the corner shape is allowed to go.

How they work together

You probably have a good conceptual understanding now of how stroke-linejoin and stroke-miterlimit work together. But depending on the stroke-miterlimit value, you might get some seemingly quirky results.

Case in point: if stroke-linejoin is set to miter, it can actually wind up looking like the bevel value instead when the miter limit is too low. Here’s the spec again to help us understand why:

If the miter length divided by the stroke width exceeds the stroke-miterlimit then [the miter value] is converted to a bevel.

So, mathematically we could say that this:

[miter length] / [stroke width] > [stroke-miterlimit] = miter [miter length] / [stroke width] < [stroke-miterlimit] = bevel

That makes sense, right? If the miter is unable to exceed the width of the stroke, then it ought to be a flat edge. Otherwise, the miter can grow and form a point.

Sometimes seeing is believing, so here’s Ana Tudor with a wonderful demo showing how the stroke-miterlimit value affects an SVG’s stroke-linejoin:

Setting miter limits in design apps

Did you know that miter joins and limits are available in many of the design apps we use in our everyday work? Here’s where to find them in Illustrator, Figma, and Inkscape.

Setting miter limits in Adobe Illustrator

Illustrator has a way to modify the miter value when configuring a path’s stroke. You can find it in the “Stroke” settings on a path. Notice how — true to the spec — we are only able to set a value for the “Limit” when the path’s “Corner” is set to “Miter Join”.

Applying stroke-miterlimit in Adobe Illustrator.

One nuance is that Illustrator has a default miter limit of 10 rather than the default 4. I’ve noticed this every time I export the SVG file or copy and paste the resulting SVG code. That could be confusing when you open up the code because even if you do not change the miter limit value, Illustrator adds stroke-miterlimit="10" where you might expect 4 or perhaps no stroke-miterlimit at all.

And that’s true even if we choose a different stroke-linejoin value other than “Miter Join”. Here is the code I got when exporting an SVG with stroke-linejoin="round".

<svg viewBox="0 0 16 10"><path stroke-width="2" stroke-linejoin="round" stroke-miterlimit="10" d="M0 1h15.8S4.8 5.5 2 9.5" fill="none" stroke="#000"/></svg>

The stroke-miterlimit shouldn’t be there as it only works with stroke-linejoin="miter". Here are a couple of workarounds for that:

  • Set the “Limit” value to 4, as it is the default in SVG and is the only value that doesn’t appear in the code.
  • Use the “Export As” or “Export for Screen” options instead of “Save As” or copy-pasting the vectors directly.

If you’d like to see that fixed, join me and upvote the request to make it happen.

Setting miter limits in Figma

Miter joins and limits are slightly different in Figma. When we click the node of an angle on a shape, under the three dots of the Stroke section, we can find a place to set the join of a corner. The option “Miter angle” appears by default, but only when the join is set to miter:

Applying stroke-miterlimit in Figma.

This part works is similar to Illustrator except for how Figma allows us to set the miter angle in degree units instead of decimal values. There are some other specific nuances to point out:

  • The angle is 7.17° by default and there is no way to set a lower value. When exporting the SVG, that value is becomes stroke-miterlimit='16‘ in the markup, which is different from both the SVG spec and the Illustrator default.
  • The max value is 180°, and when drawing with this option, the join is automatically switched to bevel.
  • When exporting with bevel join, the stroke-miterlimit is there in the code, but it keeps the value that was set when the miter angle was last active (Illustrator does the same thing).
  • When exporting the SVG with a round join, the path is expanded and we no longer have a stroke, but a path with a fill color.

I was unable to find a way to avoid the extra code that ends up in the exported SVG when stroke-miterlimit is unneeded.

Setting miter limits in Inkscape

Inkscape works exactly the way I’d expect a design app to manage miter joins and limits. When selecting a a miter join, the default value is 4, exactly what it is in the spec. Better yet, stroke-miterlimit is excluded from the exported SVG code when it is the default value!

Applying stroke-miterlimit in Inkscape.

Still, if we export any path with bevel or round after the limit was modified, the stroke-miterlimit will be back in the code, unless we keep the 4 units of the default in the Limit box. Same trick as Illustrator.

These examples will work nicely if we choose the Save AsOptimized SVG option. Inkscape is free and open source and, at the end of the day, has the neatest code as far as stroke-miterlimit goes and the many options to optimize the code for exporting.

But if you are more familiar with Illustrator (like I am), there is a workaround to keep in mind. Figma, because of the degree units and the expansion of the strokes, feels like the more distant from the specs and expected behavior.

Wrapping up

And that’s what I learned about SVG’s stroke-miterlimit attribute. It’s another one of those easy-to-overlook things we might find ourselves blindly cutting out, particularly when optimizing an SVG file. So, now when you find yourself setting stroke-miterlimit you’ll know what it does, how it works alongside stroke-linejoin, and why the heck you might get a beveled join when setting a miter limit value.


Mastering SVG’s stroke-miterlimit Attribute originally published on CSS-Tricks. You should get the newsletter.

CSS-Tricks

, , ,

The `ping` attribute on anchor links

I didn’t know this was a thing until Stefan Judis’s post:

<a href="https://www.stefanjudis.com/popular-posts/"     ping="https://www.stefanjudis.com/tracking/">Read popular posts</a>

You give an anchor link a URL via a ping attribute, and the browser will hit that URL with a web request (a literal PING) when clicked. The headers have a ping-to key with the href value of the link.

Why? Data. Wouldn’t it be nice to know what off-site links people are clicking on your website?

Even if you have Google Analytics installed, you don’t get that data by default. You’d have to write something custom or use something like their autotrack plugin with the outboundLinkTracker. Whatever you do, it is non-trivial, as in order to work, it has to:

  1. Have JavaScript intervene
  2. Prevent the default action of the link (going to the website)
  3. Track the event (send a ping somewhere)
  4. Then tell the browser to actually go to the website (window.location = …)

That’s because running a bit of JavaScript to ping your tracking service is unreliable on an off-site click. Your site is unloading and the new site loading as fast as possible, meaning that ping might not get a chance to run.

Presumably, with the ping attribute, you don’t have to do this little JavaScript dance of sending the ping before the page unloads — it will “just work.” That’s a big plus for this technique. It’s so cool to move complex ideas to lower-level languages that work easier and better.

There are heaps of downsides though. You don’t exactly get a nice API for sending along metadata. The best you could do is append a query string for extra data (e.g., was the link in the footer? or was it in a blog post?). But perhaps the biggest limitation is that it’s only for anchor links. If you were building a really serious event tracking thing, you’d want it to be useful for any type of event (not just clicks) on any type of element (not just links). So it’s not terribly surprising this is almost entirely the JavaScript’s domain.

Direct Link to ArticlePermalink


The post The `ping` attribute on anchor links appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , ,
[Top]

SVG Title vs. HTML Title Attribute

You know the title attribute? I can do this:

<div title="The Title">   I'm a div with a `title` </div>

And now if I’m on a device with a mouse pointer and hover the cursor over that element, I get…

Screenshot of standard text saying I'm a div with a title. A light gray tooltip is floating above the text next to the cursor that says The Title.

Which, uh, I guess is something. I sometimes use it for things like putting an expanded date or time on an element that uses shorthand for it. It’s a tiny bit of UX helpfulness reserved exclusively for sighted mouse users.

But it’s not particularly useful, as I understand it. Ire Aderinokun dug into how it’s used for the <abbr> element (a commonly cited example) and found that it’s not-so-great alone. She suggests a JavaScript-enhanced pattern. She also mentions that JAWS has a setting for announcing titles in there, so that’s interesting (although it sounds like it’s off by default).

I honestly just don’t know how useful title is for screen readers, but it’s certainly going to be nuanced.

I did just learn something about titles though… this doesn’t work:

<!-- Incorrect usage --> <svg title="Checkout"> </svg>

If you hover over that element, you won’t get a title display. You have to do it like this:

<!-- Correct usage --> <svg>   <title>Checkout</title>      <!-- More detail -->   <desc>A shopping cart icon with baguettes and broccoli in the cart.</desc> </svg>

Which, interestingly, Firefox 79 just started supporting.

When you use title like that, the hoverable area to reveal the title popup is the entire rectangle of the <svg>.

I was looking at all this because I got an interesting email from someone who was in a situation where the title popup only seemed to come up when hovering over the “filled in” pixels of an SVG, and not where transparent pixels were. Weird, I thought. I couldn’t replicate in my testing either.

Turns out there is a situation like this. You can apply a <title> within a <use> element, then the title only applies to those pixels that come in via the <use>.

If you remove the “white part” title, you’ll see the “black part” only comes up over the black pixels. Seems to be consistent across browsers. Just something to watch out for if that’s how you apply titles.


The post SVG Title vs. HTML Title Attribute appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, ,
[Top]

Responsive Styling Using Attribute Selectors

One of the challenges we face when implementing class-based atomic styling is that it often depends on a specific breakpoint for context.

<div class="span-12"></div> <!-- we want this for small screens  --> <div class="span-6"></div>  <!-- we want this for medium screens --> <div class="span-4"></div>  <!-- we want this for large screens  -->

It’s common to use a prefix to target each breakpoint:

<div class="sm-span-12 md-span-6 lg-span-4"></div>

This works well until we start adding multiple classes. That’s when it becomes difficult to keep a track what relates to what and where to add, remove. or change stuff.

<div class="   sm-span-12    md-span-6    lg-span-4    sm-font-size-xl    md-font-size-xl    lg-font-size-xl    md-font-weight-500    lg-font-weight-700"> </div>

We can try to make it more readable by re-grouping:

<div class="   sm-span-12    sm-font-size-xl  
   md-span-6    md-font-size-xl    md-font-weight-500  
   lg-span-4    lg-font-size-xl    lg-font-weight-700"> </div>

We can add funky separators (invalid class names will be ignored):

<div class="   [    sm-span-12     sm-font-size-xl    ],[    md-span-6     md-font-size-xl     md-font-weight-500    ],[    lg-span-4     lg-font-size-xl     lg-font-weight-700   ]"> </div>

But this still feels messy and hard to grasp, at least to me.

We can get a better overview and avoid implementation prefixes by grouping attribute selectors instead of actual classes:

<div    sm="span-12 font-size-lg"   md="span-6 font-size-xl font-weight-500"   lg="span-4 font-size-xl font-weight-700" > </div>

These aren’t lost of classes but a whitespace-separated list of attributes we can select using [attribute~="value"], where ~= requires the exact word to be found in the attribute value in order to match.

@media (min-width: 0) {  [sm~="span-1"] { /*...*/ }                [sm~="span-2"] { /*...*/ }     /* etc. */  } @media (min-width: 30rem) {  [md~="span-1"] { /*...*/ }     [md~="span-2"] { /*...*/ }     /* etc. */    } @media (min-width: 60rem) {  [lg~="span-1"] { /*...*/ }     [lg~="span-2"] { /*...*/ }     /* etc. */    }

It may be a bit odd-looking but I think translating atomic classes to  attributes is fairly straightforward (e.g. .sm-span-1 becomes [sm~="span-1"]). Plus, attribute selectors have the same specificity as classes, so we lose nothing there. And, unlike classes, attributes can be written without escaping special characters, like /+.:?.

That’s all! Again, this is merely an idea that aims to make switching declarations in media queries easier to write, read and manage. It’s definitely not a proposal to do away with classes or anything like that.

The post Responsive Styling Using Attribute Selectors appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Using the HTML title attribute

 Steve Faulkner:

User groups not well served by use of the title attribute

• Mobile phone users.
• Keyboard only users.
• Screen magnifier users.
• Screen reader users.
• Users with fine motor skill impairments.
• Users with cognitive impairments.

Sounds like in 2020, the only useful thing the title attribute can do is label an <iframe title="Contact Form"></iframe>.

Direct Link to ArticlePermalink

The post Using the HTML title attribute appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

Select an Element with a Non-Empty Attribute

Short answer:

[data-foo]:not([data-foo=""] {

Longer answer (same conclusion, just an explanation on why we might need this):

Say you have an element that you style with a special data-attribute:

<div data-highlight="product"> </div>

You want to target that element and do special things when highlighting.

[data-highlight] {   font-size: 125%;  }  [data-highlight="product"] img {   order: 1; }

That data-type attribute is part of a template, so it can have any value you set.

<div data-highlight="{{ value }}"> </div>

And sometimes there is no value! So the output HTML is:

<div data-highlight=""> </div>

But this can be tricky. See in that first CSS block above, we’re wanting to target all elements with the data-highlight attribute, buttttt, we actually only wanna do it if it has a value. If the value is blank, we want to just skip any special styling at all.

In a perfect world, we’d just remove the data-attribute from the HTML template when there is no value. But a lot of templating languages, on purpose, don’t allow logic in them that would help us put-or-not-put that attribute entirely.

Instead, we can solve it with CSS:

[data-highlight]:not([data-highlight=""] {   font-size: 125%;  }  [data-highlight="product"] img {   order: 1; }

The post Select an Element with a Non-Empty Attribute appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

The `hidden` Attribute is Visibly Weak

There is an HTML attribute that does exactly what you think it should do:

<div>I'm visible</div> <div hidden>I'm hidden</div>

It even has great browser support. Is it useful? Uhm. Maybe. Not really.

Adam Laki likes the semantics of it:

If we use the hidden attribute, we make our semantic a little better. Anybody will understand what does a “hidden” attribute means on an element.

Monica Dinculescu calls it a lie:

the hidden rule is a User Agent style, which means it’s less specific than a moderate sneeze. This means that your favourite display style will override it:

<style>   div { display: block; } </style> <div hidden>   lol guess who's not hidden anymore   hint: it's this thing </div>

So two related problems…

  1. It’s extremely weak. Literally any change to the display property other than the none value on the element with any strength selector will override it. Much like any other display property, like width or whatever, except the it feels somehow worse to have a hidden attribute actively on an element and have it not actually be hidden.
  2. The display property is sadly overloaded with responsibility. It would be way cool if hidden was a CSS property that could be in charge of the visibility/access of elements rather than the same property that controls the type of block it is. But alas, backward compatibility 4-lyfe of the web stops that (which is a good thing for the health of the web overall).

If you really love the semantics of the attribute, Monica suggests:

[hidden] { display: none !important; }

Seems like a nice addition to any “reset” or base stylesheet.

Otherwise, the classic technique of hiding things with a class is absolutely fine. I typically have a utility class:

.hide, .hidden {   display: none; }

But remember there are always a million ways to do things. I find myself regularly doing one-off hide/show mechanisms. For example, a menu that you need to toggle the visibility of with flair, but remain accessible at all times…

.menu {    opacity: 0;    visibility: hidden;    transition: 0.2s;    transform: translateX(20px);    &[data-open] {      opacity: 1;      visibility: visible;      transform: translateX(0);    } }

The post The `hidden` Attribute is Visibly Weak appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]