Frontend Masters Boost RSS Feed https://frontendmasters.com/blog Helping Your Journey to Senior Developer Tue, 23 Jul 2024 14:36:10 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.1 225069128 ::details-content Looks Helpful https://frontendmasters.com/blog/details-content-looks-helpful/ https://frontendmasters.com/blog/details-content-looks-helpful/#comments Thu, 18 Jul 2024 15:23:44 +0000 https://frontendmasters.com/blog/?p=3059 The HTML for a <details> element is generally something like:

<details>
  <summary>Spoiler alert!</summary>

  <p>Rosebud was a sled.</p>
  <p>It's true!</p>
</details>

See how I put two <p> elements in there? That’s totally fine. Everything that isn’t the <summary> is visually hidden until the <details> is open, either via the open attribute or the summary is clicked/tapped.

So if you’re trying to select “all the content”, you’re either forced to use a wrapper or use an awkward selector like details > *:not(summary). The newly-specced ::details-content looks like a nice fix for this. (hat tip).

]]>
https://frontendmasters.com/blog/details-content-looks-helpful/feed/ 4 3059
Notes On “Microfeatures I Love in Blogs and Personal Websites” https://frontendmasters.com/blog/notes-on-microfeatures-i-love-in-blogs-and-personal-websites/ https://frontendmasters.com/blog/notes-on-microfeatures-i-love-in-blogs-and-personal-websites/#respond Mon, 15 Jul 2024 23:30:33 +0000 https://frontendmasters.com/blog/?p=3017 I enjoyed Danila Fedorin’s post Microfeatures I Love in Blogs and Personal Websites. Here’s some stuff I think it cool is a great style of post that I wish more people did, especially since I was just poking at that. Maybe I’ll do my own one of these days, but I had so many thoughts while reading Danila’s, I figured I could turn that into a post.

I’m going to go through each feature with what goes through my brain. It is clearly noted “[these features] need not be applied indiscriminately” which I agree and want to underscore. These are mostly just nice ideas when appropriate.

Sidenotes

Danila mentions examples like this.

Love it. Very classy. My thinking is:

  1. Start as semantic HTML footnotes. Put the footnotes at the bottom of the article, use numbered jump links down to them, then link back.
  2. Progressively enhance to a popover, probably as a drawer.
  3. If on a large enough screen, enhance to Nuclear Anchored Sidenotes. CSS’ upcoming anchor positioning API is going to be a godsend for this.

Easily Linkable Headings

The idea here is instead of something like this:

<h2>
  <a href="#particular-header">
    #
    <span class="visually-hidden">Jump Link to Particular Header</a>
  </a>
  Particular Header
</h2>

You just make the header itself a link like:

<a href="#particular-header">
  <h2 id="particular-header">Particular Header</h2>
</a>

Huh! I just never thought to do it that way because it feels like… I dunno they aren’t really links so it feels weird linking the whole thing. But the more I think about it the more I don’t hate it. Danila is doing it and even tosses in a little yellow fade technique for good measure I see.

To me, it’s more about an authoring experience that doesn’t make you think about it at all. All headers should be linkable, automatically. I’ve long been a fan of this itty bitty WordPress plugin that does it. Whatever you use to produce HTML from written content, automate it!

GitHub does it like this, after the header.
The current design of this site does it like this, before the header.

Table of Contents

I actually moved “Easily Linkable Headlines” up a few spots so that it would come before this section. My thinking is that once you have all headers linked properly, producing a table of contents is “easy”. Loop over the headers, display. The more complicated (but optional) thing could could do is nesting the headers. Meaning h4’s are nested under the preceding h3, which is nested under the preceding h2, etc.

I would think any major CMS will have some automated way of producing these things. I hand-wrote the PHP on this site to create the ones you can see in our sidebar on all posts (that have headings).

This site’s current Table of Contents design, which is in the sidebar and has position: sticky so it hangs around as you scroll down a longer article.

Showing Page Progress

I actually disagree on this one. I think those horizontal bars that fill up as you scroll down the page are cheezy, unnecessary, and unhelpful. They do make for a pretty good demo on using Scroll-Driven Animations though!

But we just talked about Table of Contents and Danila mentions a Table of Contents that highlights where you are, and that is actually pretty rad. Agreed on that one! Maybe I can implement that to our Table of Contents one day.

Grouping Series of Posts

It’s actually silly to write a series of posts and then not clearly link them together. Definitely do that! As many ways as you kind. That’s just good wayfinding for users. Nobody is going to be mad at you for helping you find your way around.

I built this kind of widget here on Boost for that:

The Article Series block on this site’s design at the time of writing.

As I mentioned, this is a WordPress site, so I used Advanced Custom Fields (very broadly useful) and the Post Object Field Type applied to a custom Block, so I can plop one of these little “Article Series” blocks where ever I want. Then I make the block a “Pattern”, so that I can re-use the exact same version of the Block all over the series. Update one, they all update, which makes it easy as you’re publishing over time. I realize that’s pretty WordPress-specific, but it’s worth building out something for this if you publish series!

Dialogs

Heck yeah! +1 to interesting post formats. We all use all sorts of messaging services, so having that available to use as a design element with posts is a great idea. We’ve done limited versions of it sort of replicating a Discord conversation a few times, but it doesn’t yet have that back-and-forth conversational feel, it’s just a list of posts.

I’d probably make a “left” custom design and a “right” custom design so I could just pick and choose them however makes the conversation look best. Oh and it would be a great use-case for text-wrap: balance so that the actual “text bubbles” would feel rather sized to their content nicely.

Generally: art direct those articles! Make them interesting!

Code Blocks with Origin

The idea here is showing off the name of the file that you’re showing off a code block of.

I mean, sure. Why not. I could see that being an interesting bit of metadata you might want to have available sometimes. I’ve just written one zillion code blocks in posts in my life and have rarely wanted it. I usually don’t care what you name your file, it’s just a concept. In Danila’s case, it was based on user feedback about a pretty complex series of posts about a very technical subject, so point taken.

Here’s my list for both authors and users of code blocks:

  1. Syntax highlighting, server side. Subset of languages I care about.
  2. I don’t want to have to escape special characters myself.
  3. Nice design. Distinct but not distracting.
  4. A copy and paste button.
  5. Line numbers that I can turn on or off.
  6. Ability to highlight any lines.

I do like the idea of allowing for clickable links within code blocks. This is a good one for the list because I think it would be extra tricky to pull off and quite a nice touch. You either have to give up on having the code auto-escaped (so the HTML within could stay actual HTML) or do something really clever, like not escaping HTML within comments?? or something??

.el {
  /* Try the <a href="https://scroll-driven-animations.style/tools/view-timeline/ranges/">View Timeline Visualizer</a> */
  animation: reveal linear both;
  animation-timeline: view(block);
  animation-range: cover 0% cover 100%;
}

Markers for External Links

I get the idea. The little box-with-arrow icon sorta like [⤴].

I can’t get behind it though. I’d say it’s just personal preference (I don’t really care if a link is “internal” or “external”), but I’ve also never seen data on if users find it helpful or heard any particularly strong or compelling opinions about it over my years. I do like it when links that are weird/surprising are indicated though, like:

  1. Email links (e.g. mailto:)
  2. Links to PDFs
  3. Links to Media files (e.g. .mp3)

Those have way different behavior than just “go to new website” so a heads up is nice. And since they are all <a> links (probably), CSS can help:

a[href$=".pdf"]::after {
  content: " (PDF)";
}
a[href^="mailto"]::after {
  content: " (Email)";
}
/* etc. */

Danila’s idea of different markers for different destinations, while I’m personally not that into it, can be pulled off in CSS with a little indie web service.

Link Preview

I’d have a real light touch with this! It’s kind of unexpected behavior if you do something like make it a hover effect for a link.

Remember when posted about Standalone Web Components, I linked up David Darnes’ <link-peak> component which could help with this.

RSS Feeds

Yes! Old man shakes fist at internet!

If you write and publish your work on your own site for free, give me that sweet sweet RSS feed. Do it just for me. I’ll subscribe to it. I carefully curate my feeds and I love it. It’s simple technology designed to connect us.

Danila almost mentions linking up other people’s sites. Sure! Go for it! Have fun with it! You could call it a “blogroll”, that’s kind of the classic term for it. Or go even older-school with a “webring”, those are coming back a smidge. If you want to show the latest posts from other sites, that ups the difficultly and has performance implications, but it’s doable and you could have fun with that.

]]>
https://frontendmasters.com/blog/notes-on-microfeatures-i-love-in-blogs-and-personal-websites/feed/ 0 3017
YouTube Embeds are Bananas Heavy and it’s Fixable https://frontendmasters.com/blog/youtube-embeds-are-bananas-heavy-and-its-fixable/ https://frontendmasters.com/blog/youtube-embeds-are-bananas-heavy-and-its-fixable/#comments Mon, 01 Jul 2024 12:56:07 +0000 https://frontendmasters.com/blog/?p=2881 TL;DR: YouTube Embeds are like 1.3MB in size with no shared resources between multiple embeds. Using a <lite-youtube> Web Component is more like 100k, does share resources, and sacrifices no functionality.

You can put a YouTube video on any website. They help you do it. Under the Share menu right on youtube.com there is an option to <> Embed and you’ll see bit of HTML with an <iframe> in it.

<iframe>s are never wonderful for performance, but they make sense for protected third-party content.

This is what I’m getting as I write:

<iframe 
  width="560" 
  height="315" 
  src="https://www.youtube.com/embed/LN1TQm942_U?si=EfW_M4bEHEO-idL3"
  title="YouTube video player"
  frameborder="0"
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
  referrerpolicy="strict-origin-when-cross-origin"
  allowfullscreen>
</iframe>

If I were Team YouTube, I’d get loading="lazy" on there to help with performance right away. No need for videos that aren’t even visible on the page to load right away.

<iframe 
  ...
  loading="lazy"
  >
</iframe>

Plus I’d put some inline styles on there to keep the video fluid and maintain the original aspect ratio. Or you could target these and do that yourself in CSS. Here’s assuming the videos are the standard 16 / 9 aspect ratio:

iframe[src^="https://www.youtube.com/embed/"] {
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 16 / 9;
}

But… let’s not keep this HTML at all. I’m sure you read this blog post title, but let’s put a point on it:

On a page with literally nothing at all on it other than a YouTube Embed, we’re looking at:

  • 32 requests
  • 1.3 MB of data transfer
  • 2.76s to load the page on my current WiFi connection

Zach Leatherman, equally exasperated by this, noted:

The weight also grows linearly with every embed—resources are not shared: two embeds weigh 2.4 MB; three embeds weigh 3.6 MB (you get the idea).

Wow.

Looks like sizes are up a bit since Zach last looked as well.

The Appearance & Functionality

This is what you get from a YouTube Embed:

  • You see a “poster” image of the video
  • You see the title of the video
  • You see a big play button — click it to play the video

This is very little UI and functionality, which is fine! We can absolutely do all this without this many resources.

Why is it this way? 🤷‍♀️

I don’t think we have any good answers here. In fact, I heard from a little birdie who ran it up the pole that they have tested lighter embeds and found them to reduce engagement. 😭

I’m just gonna straight up say I don’t believe it. It’s like when Google told us that taking up half the screen with AI generated answers led to people clicking on third-party results more, but then refused to show data or allow us to track those clicks ourselves.

And hey — sometimes there are unexpected results in testing. That’s why we test instead of guess. But because this is so counterintuitive and offtrack for so many other similar performance testing situations, this bears deeper scrutiny. It would benefit from an opening of the methodology and data.

Like if you tell me that if you hit people with a stick and they smile more, I’m gonna want you to stop until we can look at what’s going on there.

I really wish I could find a good link for this, but there is a famous story from YouTube engineers way-back-when who made a much lighter video page and put it into testing. They found, quite counterintuitively, that average page load times went up. But with a deeper look, they found that the lighter page was able to reach more people, including people on low-power low-internet-speed devices who were able to actually use YouTube for the first time, and them using it much more slowed those averages. That’s awesome! The speed of using the site was up relatively for everyone. The metric of the average page load speed was a red herring and ultimately not meaningful.

How do we know that’s not the same kind of thing happening here?

Remember the implications of all these resources isn’t just a little inconvenience. YouTube is so enormous we’re talking incredible amounts of wasted electricity and thus carbon output. Pulling a megabyte of data off every single YouTube Embed would be an incredible win all around. I might even say not improving this is environmentally negligent.

The Solution is to Replicate the Embed Experience Another Way. There are Open Source Web Components That Do It Well.

With a little dab of irony, Google’s own performance champion Paul Irish has had a web component doing just this for years and years and years:

lite-youtube-embed

The pitch is solid:

Provide videos with a supercharged focus on visual performance. This custom element renders just like the real thing but approximately 224× faster.

Two hundred and twenty four times faster. Which of course involves much less data transfer.

And I’d like to be very clear, also does the exact same thing as the default embed:

  • You see a “poster” image of the video
  • You see the title of the video
  • You see a big play button — click it to play the video

You lose nothing and gain tons of speed, efficiency, and default privacy.

Using Lite YouTube Embed

  1. Link up the JavaScript to instantiate the Web Component
  2. Use it

You could install it from npm or copy and paste a copy into your own project or whatever. Or link it from a CDN:

import "https://esm.sh/lite-youtube-embed";

That’s like this:

But the best way to use it is right in the README:

Use this as your HTML, load the script asynchronously, and let the JS progressively enhance it.

<script defer src="https://cdnjs.cloudflare.com/ajax/libs/lite-youtube-embed/0.3.2/lite-yt-embed.js"></script>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lite-youtube-embed/0.3.2/lite-yt-embed.css" integrity="sha512-utq8YFW0J2abvPCECXM0zfICnIVpbEpW4lI5gl01cdJu+Ct3W6GQMszVITXMtBLJunnaTp6bbzk5pheKX2XuXQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<lite-youtube videoid="ogfYd705cRs" style="background-image: url('https://i.ytimg.com/vi/ogfYd705cRs/hqdefault.jpg');">
  <a href="https://youtube.com/watch?v=ogfYd705cRs" class="lty-playbtn" title="Play Video">
    <span class="lyt-visually-hidden">Play Video: Keynote (Google I/O '18)</span>
  </a>
</lite-youtube>

With async loaded JavaScript, note the background-image is put into the HTML so it can all look right before the JavaScript loads.

Alternatives

]]>
https://frontendmasters.com/blog/youtube-embeds-are-bananas-heavy-and-its-fixable/feed/ 11 2881
Popovers Work Pretty Nicely as Slide-Out Drawers https://frontendmasters.com/blog/popovers-work-pretty-nicely-as-slide-out-drawers/ https://frontendmasters.com/blog/popovers-work-pretty-nicely-as-slide-out-drawers/#comments Mon, 24 Jun 2024 19:54:13 +0000 https://frontendmasters.com/blog/?p=2806 I remain a little obsessed about the popover attribute. This innocuous little HTML attribute produces an accessible and design-friendly “popup” UI/UX effect for little effort. I think the “tooltip” is generally the top use case for this feature, which is now well-supported across the board.

First, we looked at how to use popovers for tooltips. Because the anchor positioning API isn’t as well-supported yet, this leveraged JavaScript to do the positioning.

Second, we looked at progressively enhancing footnotes into tooltips. This technique ultimately checked if the browser supported both popovers and anchor positioning and if so would do native popups, otherwise fallback to being a normal footnote, which is perfectly fine.

This time, we’ll look at a tooltip design that just doesn’t require the anchor positioning API or any JavaScript positioning at all. We’ll make the tooltips slide out from the bottom of the screen instead.

example of a popover opening as a drawer

I guess I’ll have to admit this is a series:

Article Series

Closed = Footnote; Open = Drawer

This idea of drawer-based popups don’t require this fancy dance of having the content already visible on the page as a footnote. I just really like the idea. In CSS, the ultimately expresses itself like this:

/* Display as a footnote */
[popover] {
  display: list-item;
  ...

  /* Display as a drawer */
  &:popover-open {
    position: fixed;
    ...

  }
}

This will ultimately require a bunch of declarations to force the content into both shapes. Such is CSS.

Progressive Enhancement Happens at the Link/Button Level

Footnotes, the “fallback” for this, require an <a> link to jump down to them. Whereas the popups require a <button> to work. So we actually need to display both right next to each other:

<a class="footnote-anchor" href="#ref_1"><sup>1</sup></a>
<button popovertarget="ref_1">1</button>

You could do this either-way-around, but here we’ll hide the anchor links by default and only show them if popups aren’t supported:

.footnote-anchor {
  display: none;
}
html.no-popovers {
  .footnote-anchor {
    display: inline;
  }
  [popovertarget] {
    display: none;
  }
}

We have this no-popovers class via:

if (!HTMLElement.prototype.hasOwnProperty("popover")) {
  document.documentElement.classList.add("no-popovers");
}

The Sliding Door

The trick to a drawer sliding out from the bottom of the screen is:

  1. Fixed positioning of the drawer
  2. Translated off the page the height of itself
  3. Translated on to the page when opened

That largely looks like this:

[popover] {
  ...
  
  &:popover-open {
    z-index: 1;
    position: fixed;
    inset: auto;
    bottom: 0;
    left: 0;
    margin: 0;
    width: 100vi;
    padding: 2rem;
    background: lavender;
    box-shadow: 0 -1rem 5rem oklch(0% 0 0 / 0.33);

    animation: slide-open 0.2s;

    /* Make sure the popup isn't screen-covering */
    max-block-size: 50dvh;
    overflow: auto;
  }
}

I was thinking we could pull off the slide-in of the drawer using @starting-style and a transition, but it turns out you can set the starting style of just the open state like we’d need here. Fortunately, we can just call a simple keyframe animation to do the trick:

@keyframes slide-open {
  0% {
    transform: translate(0, 100%);
  }
  100% {
    transform: translate(0, 0);
  }
}

Especially nice on mobile, but looks good on desktop too.

The drawer just seems to make sense on the mobile screen. I don’t think positioning the popup next to the button would even be that helpful, the drawer is nicer.

But even on a larger screen it’s still fairly nice. We can take a little extra care to looslely center things a little text-wrap: balance; doesn’t hurt.

Demo

Article Series

]]>
https://frontendmasters.com/blog/popovers-work-pretty-nicely-as-slide-out-drawers/feed/ 2 2806
Footnotes Progressively Enhanced to Popovers https://frontendmasters.com/blog/footnotes-progressively-enhanced-to-popovers/ https://frontendmasters.com/blog/footnotes-progressively-enhanced-to-popovers/#comments Wed, 19 Jun 2024 11:41:27 +0000 https://frontendmasters.com/blog/?p=2743 Michelle Barker is onto an excellent idea in Progressively Enhanced Popover Toggletips. Her idea is that footnotes are the perfect sort of thing to make popovers. You know popovers: It’s like when I put a superset1 number in a sentence (like I just did) and then link it down to the bottom of the post to explain something in more detail which would have been distracting detail to put in the paragraph itself. But “jumping down” like <a href="#footnote-1"> is also distracting. Why not just open the extra information in a little popup? Indeed!

I like the idea of “doing both”. As Michelle says:

We could also hide the list when anchor positioning is supported, but I think it’s also more user-friendly to include references as a list in addition to within the document.

But then I read:

A small downside is that this approach requires a bit of content duplication.

The way Michelle did it was to put an <ol> of footnotes at the bottom as usual, and then also put the [popover] footnotes up in the content as well, which is the duplication.

The duplication isn’t that big of a deal. It just could be a little annoying for some readers (uh, yes, I already read this thank you). It mostly sucks because it makes them harder to maintain. You’d have to make identical changes manually in two places. If that’s no problem, Michelle’s technique is sound and you could use it as-is!

But… it got me thinking that there must be a way to re-use the same content for both!

Article Series

Attempt 1) Duplicates via JavaScript

My first take was that we gotta stop the manual content duplication. That’ll be a huge pain to maintain. So let’s do the duplication of the footnote list in JavaScript, hide it both visually and from screen readers as the original list is still there, and use the duplicates for the popovers.

Since that original list is still there, we can test the browser support for popovers and just entirely bail out if the support isn’t there.

// browser supports popovers
if (HTMLElement.prototype.hasOwnProperty("popover")) {

}

Then we’ll:

  1. Clone the existing list of footnotes
  2. Adjust the IDs so we don’t have duplicate IDs
  3. Add the popover attributes
if (HTMLElement.prototype.hasOwnProperty("popover")) {
  // find the list of footnotes and clone it
  const references = document.querySelector(".references");
  const duplicateReferences = references.cloneNode(true);
  
  // hide the duplicate from screen readers before re-injecting it into DOM
  duplicateReferences.setAttribute("aria-hidden", true);
  references.parentNode.insertBefore(duplicateReferences, references.nextSibling);
	
  // loop over each footnote to make a popover
  const popovers = duplicateReferences.querySelectorAll("li");
  popovers.forEach(popover => {
    popover.id = `ref_${popover.id}`;
    popover.setAttribute("popover", true);
  });
}

Looking in the web inspector we can see now that both lists are there:

The <button> elements which trigger the popups are still up above in the content, referring to these new popovers that now exist. In fact both the link and the button are both there:

<a class="popover-replace" href="#1"><sup>1</sup></a>
<button popovertarget="ref_1"><sup>1</sup></button>

People will only ever see/use one or the other. There is an <a> link there by default, then if popovers are supported, it’s replaced by the button. That was already in Michelle’s code:

[popovertarget] {
  display: none;
}

@supports (anchor-name: --ref_1) {
  [popovertarget] {
    display: inline;
    ...
  }
}

So that’s this!

Attempt 2) The Original List can be Popovers Too

That previous attempt required JavaScript, which doesn’t bother me really as it’s progressive enhancement, but it’s not always clear where JavaScript like that that spreads across different areas of a page would go, and may be a bit more fragile.

Can’t the footnotes at the bottom of the page… just be the popovers themselves? They can! Mostly!

The first trouble is that adding the popover attribute immediately makes them hidden. So the trick is to un-hide them and style them as you want them as a list. Then when they are open, which we know with the :popover-open pseudo-class, we can style them like popovers.

/* closed */
[popover] {
  display: list-item;
  position: relative;
  border: 0;
  padding: 0;
  width: auto;
  overflow: visible;

  /* open */
  &:popover-open {
    display: block;
    margin: 0;
    padding: 1rem;
    background: lavender;
    border-radius: 0.5rem;
    max-width: 15rem;
    ...
   }
}

The first side-effect here is that when any of these popovers are open, the footnote in the list below disappears. The content literally transports to the new popover location. So that causes a bit of reflow and you might not like it for that reason alone. But it works!

There is a second side-effect here. The list of footnotes-become-popovers are forced to be display: list-item so they are visible and have numbers and such. If you leave them as that when you move them into popover position, the little number marker will come with it. You can hide it:

[popover] {
  &:popover-open {
    &::marker {
      content: "";
    }
  }
}

If you make the popover, say, display: block instead, this immediately breaks the automatic list numbering. You’ll need to bring your own list numbering that is based on counters instead.

.references {
  counter-reset: item;
  > li {
    counter-increment: item;
    &::marker {
      content: counter(item) ") ";
    }
  }
}

Others?

There are upsides and downsides to both of the above techniques. Mostly they focus on solving content duplication.

There is another thing they fail at though. Michelle notes:

I’m making use of the :has pseudo-class to position the little arrows attached to the bubbles when the popover is open, by styling the ::before pseudo-element of the button.

My two techniques fail at having the little arrow be present because the DOM position of the button with target and popover aren’t next to each other anymore. You might imagine the little pointer off the popover bubble being part of the bubble itself, but no, Michelle cleverly made it part of the button instead, so it’s always pointing at the correct place. I love that.

If you wanted to preserve that, you could write JavaScript that duplicates the footnote popovers like I did in the first example, but then place them within the content (likely with aria-hidden to avoid duplicate content awkwardness) like in Michelle’s original demo.

I’ll leave that as an excercise for you readers if you wish to take it on. I’d love to see it, or any other interesting variations.

Article Series


  1. My favorite part about footnotes is the perfect excuse to use the <sup> element. ↩︎
]]>
https://frontendmasters.com/blog/footnotes-progressively-enhanced-to-popovers/feed/ 1 2743
Here’s What We Learned From the First State of HTML Survey https://frontendmasters.com/blog/state-of-html-2023-results-2/ https://frontendmasters.com/blog/state-of-html-2023-results-2/#respond Mon, 27 May 2024 14:01:15 +0000 https://frontendmasters.com/blog/?p=2404
Frontend Masters is a sponsor of the State of JS, CSS, and HTML surveys.  

We just published the results for the first-ever State of HTML survey, the results of months of hard work not only on my part, but also from Lea Verou, who designed the survey questions, and many volunteers helping out with translation, accessibility, testing, and much more. 

The survey was a success to say the least, with over 20,000 respondents taking part and answering up to 90 questions! And we’re hoping the resulting data will prove to be a useful resource for the web dev community for years to come.

But we also know not everybody has the time to parse through pages of stats and data visualizations. So if that’s you, here’s a quick recap of the most interesting findings from the survey. 

People Love Datalist

A key innovation of this year’s survey was the ability for respondents to not only specify their experience with a feature (“used it”, “heard of it”, “never heard of it”), but also their sentiment, in other words whether they were happy/unhappy, interested/uninterested, etc, 

And the feature that came in first in terms of positive sentiment was datalist, with 55.4% positive sentiment and only 3.9% negative sentiment (the rest being neutral). 

Datalist is a not-so-new element (it became widely supported by browsers around 2019) that lets you create an autocomplete/typeahead component without any JavaScript. And while it may not be as flexible as your typical JavaScript implementation, it’s still quite handy — and way easier to get right!

Other favorites included the newly-baseline’d Popover API and its cousin, the dialog element, both similar to datalist in that they emulate natively features that developers have long relied on JavaScript for. 

In other words, even though many of us have embraced JavaScript front end frameworks over the past decade, at the end of the day we’d still rather let the browser take care of things!

…But Hate Forms

While respondents shared their love for many web APIs, there was one area where they made no secret of their discontent: forms

We asked respondents what were their pain points around HTML forms, and that question collected over 11,000 responses — and I’m talking about freeform comments, not just clicking a checkbox!

So what were people so mad about? Number one with over 3,600 comments was styling, or the lack thereof. The select element especially was a recurring culprit, which makes sense for such an omnipresent UI element – and which is why there’s a proposal in the works for a new, easier-to-style alternative. 

Apart from styling issues, respondents shared their various gripes about other form input elements, chief among them <input type="date" />. As one respondent mentioned, “date inputs are not really usable and not fully accessible”.

Validation was also a big pain point, especially when trying to do more advanced tasks such as validating one field conditionally based on the value of another. 

And it’s worth pointing out that form input elements also came in first both when respondents were asked about existing HTML features or browser APIs they were unable to use because of browser differences or lack of support, and features they were unable to use for other reasons.

Web Components… Exist

When it comes to web components, the developer community is roughly split into three camps. The first one thinks they’re the next big thing, and that they’re going to take over the industry any day now, just you see!

The second camp believes they are a doomed initiative, especially when front end frameworks already offer all the same features and more. 

And finally, the third camp has been quietly using web components here and there when they make sense, and mostly keeping to themselves. 

It’s fair to say that camp #2 was well represented in the survey, with many complaining about web component’s lack of interoperability with React, Vue, and other frameworks; or even questioning the need for them altogether. And 3 out of the top 5 features with the most negative sentiment were also web components-related. 

Among people who did use web components, yet again styling & customization was a big concern, showing that we might want more ready-made solutions; but we still want to be able to adapt them to our needs. 

Yet as with the rest of the web platform, web components are constantly evolving. And until their time does come, it’s totally fine to only use them on an ad-hoc basis. 

We Need Datatables, Tabs, and Switches, and We Need Them Yesterday!

Respondents were asked what elements they’d add to HTML if they could pick anything, and the top three results were datatables (tables with sorting, filtering, etc. controls), tabs, and toggles/switches. 

This is interesting because all three are components that are relatively rare in static sites (although dark mode toggles are becoming a thing), but extremely common in any kind of dashboard or app. 

This recalls the age-old dichotomy between documents and apps, and although we’ve long since moved past the idea that HTML is only good for describing static content, the fact that these elements are still missing shows that we haven’t quite embraced HTML as an app-centric platform either yet. 

The Divide Is… Closing?

Five years ago, some random guy you’ve probably never heard about named Chris wrote a landmark article entitled The Great Divide. In it, Chris talks about what Brad Frost would later call the “front-of-the-front-end” (HTML/CSS) and “back-of-the-front-end” (JavaScript) split. 

Granted, the survey audience may not be totally representative of the industry at large, and about 12% of respondents found the survey through having answered the State of JS survey before. 

But at least according to our data, this divide may not be as stark as once thought. About 22% of survey respondents used Next.js for example, and when asked how they allocated their time between writing HTML/CSS and JavaScript/TypeScript code, 59% said they spent more than half their time writing JavaScript – even though the survey was clearly aimed at people interested in HTML.

In my own experience at least, even if you work primarily on the “front” of the front end, very often the HTML and CSS you deal with will be generated by a JavaScript framework of some kind, meaning you can’t help but step in the back to see what’s going on from time to time. 

It’ll be interesting to see how this trend evolves. As HTML gains more features, will the need to cover both ends of the front end spectrum diminish? Or maybe, back-of-the-front-end developers will realize they don’t need to hit every single nail with the JavaScript hammer after all?

Stay Tuned

If only there was a way to figure this out! Like for example, some kind of recurring survey that would help us track these trends over time… But wait, there is! The 2024 edition of the State of HTML survey will take place later this year, and you can already sign up for our mailing list to be notified when that happens. 

In the meantime, go check out the full 2023 results and let us know if you find any insights of your own!

]]>
https://frontendmasters.com/blog/state-of-html-2023-results-2/feed/ 0 2404
State of HTML 2023 Results https://frontendmasters.com/blog/state-of-html-2023-results/ https://frontendmasters.com/blog/state-of-html-2023-results/#respond Mon, 20 May 2024 17:33:16 +0000 https://frontendmasters.com/blog/?p=2267 The State of HTML 2023 Results are out!

I thought this survey was more interesting to take than reading these results. It’s not that the results aren’t interesting. I’m almost impressed by how low the “used it” percentages are for certain features, like less than half of people have used a <details>?? And 28% are itching to use tabindex again? 😬 It’s just that in taking the survey we were all reminded of how many interesting things are going on in HTML land and likely learned about a good many things, like there is a Badging API??

I like Lea’s conclusion:

Some argue that improving HTML is futile, but the survey resoundingly demonstrates the contrary. Developers crave more interactive HTML elements: not only were interactive elements like <datalist> or the Popover API among those accumulating the most positive sentiment across all categories, but in addition all top missing elements were interactive widgets.

That new Popover API is extremely awesome, in no small part because it can be used in HTML alone.

]]>
https://frontendmasters.com/blog/state-of-html-2023-results/feed/ 0 2267
Exactly How to Deploy Local Files to Make a Live Website https://frontendmasters.com/blog/exactly-how-to-deploy-local-files-to-make-a-live-website/ https://frontendmasters.com/blog/exactly-how-to-deploy-local-files-to-make-a-live-website/#respond Fri, 17 May 2024 13:57:33 +0000 https://frontendmasters.com/blog/?p=2018 This post addresses a common question we get from the community:

What’s the simplest way to deploy a website so I can share it with other people?

Cutting to the chase:

  1. Sign up for Netlify
  2. Go to Drop
  3. Drop the folder of files there
  4. Done

I’ll walk you through all this below, I just wanted to be clear about what we’re doing. We’re trying to go from playing around with code on your local computer to deploying a real website! The requirements are that the process is straightforward (dare I say: “easy”) and the service has a free tier. The goal with this article is to give you direct steps, not confuse the issue with too many considerations and options.

Now let’s get into more detail.


You’ve got some files that make a website.

Maybe those files are:

index.html
style.css
script.js

Or maybe they are like this:

images/
logo.png
hero.png
background.jpg
index.html
about.html
contact.html
style.css

We’ll call them (and you might hear them being referred to as) “static files”. These files exist on your computer. Maybe you created them yourself or you exported a Pen from CodePen. You can look at them in a web browser and it looks like a website.

The example website we’ll use here is the wonderful Personal Portfolio Page from Tiffany Du. The file:// URL above will work on my computer, but not yours!

Now you want it to be a real website on the real internet.

Good on ya. This is a powerful moment. Your creation is about to be viewable by anyone in the world. Rather than complicate things with options, let’s look at one option that will get the job done. Then we’ll talk about where to go from there.

1) Sign up for Netlify

This is not an ad for Netlify. We have no affiliation. Sign up here.

There are other options, and we’ll cover those later. We’re picking a path forward and going for it. Truth be told, Netlify is a good host particularly for static files like this and has a generous free starter plan. You can grow with Netlify as they ultimately handle any amount of traffic and have lots of advanced features as you need them.

2) Find the Folder of Files on your Computer

The folder is key here. You want to be able to select the folder that contains that initial index.html file that is the home page of your site.

Here’s mine, just sitting on my Desktop.

It could be anywhere on your computer, depending on where you created it or downloaded it. You just need to be able to find it for the next step. It doesn’t matter if you’re using macOS, Windows, or Linux, you’ll be able to find and select the folder somewhere.

If you’ve exported from CodePen…

You’ll get a .zip file that you can double-click to “extract” into a folder. Inside that folder you’ll see a dist folder, src folder, and some other files. It’s the dist folder that you’ll use for the next step here.

3) Go to Netlify Drop

Be logged in to Netlify and go here: https://app.netlify.com/drop

You can use this Drop app while logged out, but the resulting site is password-protected and only stays online for 1 hour. Being logged in will remove those restrictions, and unlock more options you’re very likely to want afterward, like customizing the URL.

4) Drop the Folder into the Drop Zone

Just like this:

You can see in the video that as soon as you’ve dropped the folder, the site instantly deploys, and you’ll be given a URL where the site is live at. You’re essentially done at this point! You can also see in the video that I changed the URL that I was auto-assigned to something a bit more readable.

Congrats! You’ve got your website live. I hope it feels good. 😎

Doing More

The URL you’re given from Netlify is customizable, but it’s still what is called a subdomain. In that quick video above, I customized it to:

https://my-cool-porfolio.netlify.app

Where my-cool-porfolio is the customizable part. Subdomains are fine. I actually quite like them… when they are your subdomain. It’s reasonable, and I’d argue a good idea, to have your own domain name. Something like:

https://your-name.com

The dashboard area in Netlify will essentially walk you through this. Domain names are never free though, so this part will cost money on a yearly basis.

Remember there are lots of fun “top level domains” (TLDs) as well. That is, the .com part of website.com. I’d encourage you to have fun there. Get yourself a .me, .dev, or heck, there is even a .portfolio you could get. I use .net myself.

Alternatives

There are plenty of other hosting services that can do this job. All these listed here are fairly major players, are somewhat designed around hosting a static file website, and (mostly) have free tiers.

Hosting ServiceAdvantagesDisadvantages
CloudflareCloudflare Pages has a drag and drop deployment option and advanced features much like Netlify and Vercel.Nothing major. Largely just as easy as Netlify and similar features.
VercelVercel is a very comparable service to Netlify. It is essentially designed for this.Requires code be in a Git repository.
GitHubGitHub Pages is designed for this. If your code is on GitHub anyway, this can be a natural choice. Note that GitLab also has pages, as well as Bitbucket.You’ll need to use Git. Learning Git is a great idea, but for absolute beginners this might be too much. Using a custom domain is more difficult. No advanced features to grow into.
AWSAWS Amplify is designed to be the easy version of using AWS tools, and focuses on deploying sites. They offer a similar drag-and-drop deployment (screenshot). Getting set up with an AWS account and generally navigating AWS at all nobody would call easy.
Google FirebaseFirebase Hosting is largely in the same bucket as all of the above. Requires CLI. People don’t generally use Firebase just for static hosting. It’s more commonly used for their realtime database features.
Microsoft AzureAzure Static Web Apps is Microsoft’s product in the category that is largely in the same bucket as all of the above.Just feels a little jankier than many others to me, although if you use other Azure products perhaps it feels more at home. Requires code to be in Git.
RenderRender Static Sites is largely in the same bucket as all of the above. Hosts lots of other types of sites as well, so you could potentially have a single host for different types of sites. Requires code be in a Git repository.
KinstaKinsta Static Site Hosting is largely in the same bucket as all of the above. Hosts lots of other types of sites as well, so you could potentially have a single host for different types of sites. Requires code be in a Git repository.
SurgeAn early no-frills classic in this space.Requires CLI. Feels abandoned.
ForgeLooks like there is only a free trial, no free tier. But I literally couldn’t sign up to check it out, it felt entirely broken.
Static.appLooks like a pretty nice option! Drag and drop uploading. Very streamlined interface. Only free trial, no free tier
Tiiny HostAlso looks like a pretty nice option. Drag and drop uploading. Very streamlined interface. I’ve seen a bunch of spam hosted on these URLs which makes me nervous.

Let us know what you’ve used or tried!

]]>
https://frontendmasters.com/blog/exactly-how-to-deploy-local-files-to-make-a-live-website/feed/ 0 2018
Using the Popover API for HTML Tooltips https://frontendmasters.com/blog/using-the-popover-api-for-html-tooltips/ https://frontendmasters.com/blog/using-the-popover-api-for-html-tooltips/#comments Mon, 06 May 2024 16:50:59 +0000 https://frontendmasters.com/blog/?p=2027 Can it be done? This plucky front-end developer intends to find out.

Can we do it?

We looked at the Popover API and how it’s made it’s way across all browsers already just last week. One of the things I should have done is looked at the accessibility considerations more closely. Thanks to Melanie Sumner there is a great explainer with demos. I tried to adhere to the points made in there the best I could while making a classic tooltips experience, and we’ll do a bit of a review at the end where deviations happened.

Article Series

Starting With HTML

This is actually my favorite part, as remember, this API can be used entirely in HTML. That rules. Remember when we got <details> where you could build an interactive open/close disclosure widget thing with just HTML? That also rules, but this is even cooler.

One small weirdness though, it only works in HTML alone when a <button> is the “invoker” of opening the popup. So in the case of a tooltip, that button might come right in the middle of a sentence like.

<p>
   This blog post was written by 
   <button popovertarget="popover-chris-coyier">
     Chris Coyier
   </button>
   the genius.
</p>

Then elsewhere in the DOM (the location of which doesn’t effect the core functionality):

<div id="popover-chris-coyier" popover role="tooltip">
  <img src="/images/chris.jpg" alt="A portrait of Chris Coyier in a tuxedo." width="100" height="100">
  <h4>Chris Coyier</h4>
  <p>Handsome fella.</p>
</div>

Note I’m calling this an HTML Tooltip, because what pops up isn’t text alone, which you might argue can be done with the title attribute. These popovers are far more flexible, allowing you to style them and can contain anything HTML can.

The weird part here is the button smack in the middle of the paragraph. That’ll be a bit awkward styling-wise, but that’s surmountable. Mostly I don’t know if that’s “cool” screen-reader wise. So if someone know’s, feel free to chime in. If it’s not cool, we might have to think about using a different element that is cool and relying on JavaScript to invoke the popup.

The Basic CSS

I say basic, because we cannot to tooltip-like styling in CSS for these yet. That is, we cannot position them next to the button that invoked them. We’ll get that, someday, when we can use the Anchor Positioning API.

But we can do everything else that we want in terms of styling.

For one thing, let’s make the the middle-of-text look of the button look like something you can click. That’s something Melanie pointed out as a requirement. Rather than just being blue and underlined like a normal link, I’ll add an icon so it indicates slightly different behavior. We also need to undo basic button styling so the button looks more like just some text. I usually have a class for that I call “text-like”. So:

button[popovertarget].text-like {
  border: 0;
  background: none;
  font: inherit;
  display: inline-block;

  color: #1e88e5;
  text-decoration-style: dashed;
  text-decoration-line: underline;
  text-decoration-color: #42a5f5;
  text-underline-offset: 2px;
  overflow: visible;
  

  padding: 0 1.1rem 0 0; /* space for icon */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' width='100' title='question-circle'%3E%3Cpath fill='%231e88e5' d='M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z' /%3E%3C/svg%3E");
  background-size: 0.8em;
  background-repeat: no-repeat;
  background-position: center right 1px;

  &:focus,
  &:hover {
    text-decoration-color: lightblue;
    text-decoration-style: solid;
  }
}

That leads to a within-paragraph look like this:

Then if we apply some super basic styling to the [popover] element itself, we can get a popover opening exactly in the middle of the page like this:

A couple of notes here:

  • I did not use any ::backdrop styling to style the rest of the page behind the popover. I feel like that may be a bit of an anti-pattern if using for tooltips. I don’t see any need to mess with the rest of the page when a tooltip is open.
  • I wanted to use flexbox on the popup, but that caused an issue, because display: flex; overrides the default display: none; of the popup, making it visible all the time. Instead, you can use [popover]:popover-open { } to apply it only when the popover is open. Or use an internal wrapper or whatever.

The Functional JavaScript

We need JavaScript here for two jobs:

  1. Normal tooltip behavior suggests you should be able to hover over an element and the tooltip will appear. That cannot be done in HTML alone. Maybe it could be done in CSS somehow with an animation delay or something, but it’s likely a bit more straightforward in JavaScript.
  2. Again, CSS doesn’t have anchor positioning yet, so we’ll do positioning with JavaScript.

These are both progressive enhancements, which is nice. So if either thing fails, the tooltip should still work.

The Hover Delay

For the delay, we’ll start a timer when the mouse cursor enters a button that opens a popup, if the timer finishes, we’ll open it. If the mouse cursor leaves before the timeout, we’ll clear that timeout:

const popoverButtons = document.querySelectorAll(
  "button[popovertarget]"
);

popoverButtons.forEach((button) => {
  let timeout = 0;
  button.addEventListener("mouseenter", () => {
    const target = button.getAttribute("popovertarget");
    const popover = document.querySelector("#" + target);
    // delay opening
    timeout = setTimeout(() => {
      popover.showPopover();
    }, 1500);
  });

  button.addEventListener("mouseleave", () => {
    clearTimeout(timeout);
  });
});

The Positioning

I went for a library called Floating UI to do this. I came across it the other day while using a library called Shepherd JS for creating tours (example). Shepherd uses it for positioning the steps of the tour, which are usually not far away from what an HTML tooltip might look like.

The .showPopover() API is what opens the popup, so the trick is positioning it as it is being opened.


popoverButtons.forEach((button) => {
  let timeout = 0;
  button.addEventListener("mouseenter", () => {
    const target = button.getAttribute("popovertarget");
    const popover = document.querySelector("#" + target);
    // delay opening
    timeout = setTimeout(() => {
      popover.showPopover();
      computePosition(button, popover, {
        placement: "top",
        middleware: [flip(), shift({ padding: 5 }), offset(6)]
      }).then(({ x, y }) => {
        Object.assign(popover.style, {
          left: `${x}px`,
          top: `${y}px`
        });
      });
    }, 1500);
  });

  button.addEventListener("mouseleave", () => {
    clearTimeout(timeout);
    button.removeAttribute("style");
  });
});

All that computePosition stuff with the middleware is just how Floating UI works. The flip() function is especially nice, which is essentially “edge detection”. Now the popover will attempt to be positioned on top like this:

But if there is no room on top, because that’s where the edge of the browser window is, it will “flip” to the bottom like this:

Nice.

Demo

Review

  • ✅ The links that open popups looks like that’s probably what they will do.
  • ✅ The links the trigger the popups work. They can be clicked to open (and close) the popup. JavaScript provides a hover-to-open effect as well, mimicking title behavior.
  • 🤷‍♀️ Unsure if a <button> in the middle of a <p> where the text is part of the sentence is acceptable from an accessibility perspective.
  • 🤷‍♀️ Unsure where the perfect DOM Positioning of the popup would be. My gut tells me to treat it like a footnote, putting them at the end of the main content they apply to. This seems like it would matter quite a bit for something like syndication/RSS where they might just appear as additional paragraphs without context. Or possibly right after the text element that has the popup so they are closer contextually.
  • 🤷‍♀️ I would probably always use popover="hint" to allow for multiple popovers to be open at once in a tooltip scenario, but it’s unclear if that will happen or if that will be the naming.

Article Series

]]>
https://frontendmasters.com/blog/using-the-popover-api-for-html-tooltips/feed/ 4 2027
The HTML, CSS, and SVG for a Classic Search Form https://frontendmasters.com/blog/the-html-css-and-svg-for-a-classic-search-form/ https://frontendmasters.com/blog/the-html-css-and-svg-for-a-classic-search-form/#respond Thu, 25 Apr 2024 23:38:05 +0000 https://frontendmasters.com/blog/?p=1821 Let’s build a search form that looks like this:

That feels like the absolute bowl-it-down-the-middle search form right now. Looks good but nothing fancy. And yet, coding it in HTML and CSS I don’t think is perfectly intuitive and makes use of a handful of decently modern and slightly lesser used features.

The Label-Wrapping HTML

At a glance, this looks like an <input> all by itself. Perhaps the placeholder text is pushed in with some text-indent or something and an <svg> icon is plopped on top. But no, that’s actually harder than what we’ve done here. Instead we’re going to wrap the input in a label like this:

<label class="searchLabelWrap">
  Search
  <input type="search" placeholder="Search" class="searchInput" name="s">
</label>

This wrapping means the label and input are automatically tied to each other (e.g. clicking the label will focus the input) without having to use the for attribute and a matching id.

We’re also using the search type here on the input, which is semantically correct, but also gives us the free UX of having a ✖️ “clear search” icon in the input for free.

Wrapping All That in a Search and Form element

HTML now has a <search> element, so again that’s a semantically smart choice, and we’ll also use a <form> element so that submitting the search can be done with the Enter key. Gotta think UX! If you don’t like the extra wrapper, you could put role="search" on the <form>, but I like it:

<search>
  <form action="/search" method="GET" id="searchForm">
    <label class="searchLabelWrap">
       ...
    </label>
  </form>
</search> 

The GET method means it will append our search term as a search parameter which is usually a desirable trait of a search form. The name attribute of the input will be the search param key. That’s looking pretty solid right there.

Hiding the Label, Adding an Icon

We definitely need there to be a text label for the input for screen readers, but since we’ll be visually marking the input with both a visual icon and placeholder text, I think it’s OK to hide the text label while leaving it accessible.

<label class="searchLabelWrap">
  <span class="visually-hidden">Search</span>
  <svg viewBox="0 0 512 512" aria-hidden="true" class="icon">
    <path d="..." />
  </svg>
  <input type="search" placeholder="Search" class="searchInput">
</label>
.visually-hidden {
  position: absolute;
  left: -9999px;
}

Label Wrapping Styling

Without any CSS, we’re in this sort of situation:

Perfectly functional, but we’ve got work to do. Visually, we want the icon to appear inside the “input” area. So we’ll actually apply the background to the searchLabelWrap instead here, and wipe out all the styling on the input itself. While we’re at it, let’s think about Dark Mode/Light Mode and use the newfangled light-dark() function. This is very new so, ya know, do what you gotta do. We’ll keep things aligned with flexbox and apply very chill other styles:

.searchLabelWrap {
  display: flex;
  gap: 0.5rem;
  background: light-dark(var(--gray-light), var(--gray-dark));
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
}

.searchInput {
  border: 0;
  outline: 0; /* focus style on parent */
  background: transparent;
  font: inherit;
}

We’re doing the sin of removing the focus style on the input, which isn’t a very accessible thing to do. So we gotta bring that back!

Focus Within FTW

It’s actually the input itself which receives the :focus, but we can target the parent here instead. Maybe use :has() you say? Like :has(input:focus) could work, but there is actually a cleaner way here:

.searchLabelWrap {
  ...

  &:focus-within {
    outline: 2px solid var(--focus-blue);
    outline-offset: 2px;
  }
}

I love :focus-within it’s so cool. It was kinda the OG has and it was theorized when it came out that it could be a gateway to :has() and that’s totally what happened.

Also notice the outline-offset there. I think that’s a nice touch to push the somewhat beefy outline away a smidge.

The Icon

I’m a fan of just using inline SVG for icons. No network request and easy to style my friends. Here’s one:

<svg viewBox="0 0 512 512" aria-hidden="true" class="icon" width="
20">
  <path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z" />
</svg>

I like tossing a width on there because an <svg> with a viewBox before CSS loads can load super wide on the screen and it’s akward. CSS will come in and make it right here:

.icon {
  width: 1rem;
  aspect-ratio: 1;
  fill: currentColor;
}

You could apply different styling, but here I’m making the icon text follow the text color so it’s easier to update. The icon is also essentially in a square area hence the simple aspect-ratio.

Colors

I used a few --custom-properties as we went. I’ll define them here at the root, as well as ensure our page knows we’re intending to support both modes:

html {
  color-scheme: light dark;

  --gray-light: #eee;
  --gray-dark: #333;
  --focus-blue: #1976d2;
}

body {
  background: light-dark(white, black);
  color: light-dark(black, white);
  font: 100%/1.5 system-ui, sans-serif;
}

That’ll do use nicely, finishing things off.

Demo

]]>
https://frontendmasters.com/blog/the-html-css-and-svg-for-a-classic-search-form/feed/ 0 1821