Impressive Webs: Recent Episodes

None

Articles on Front-end Web Development

View Details

I like to play beach volleyball here in the Toronto area. I also watch beach volleyball on YouTube, which includes a lot of live streams from the AVP league in the US. It’s a fun sport that I recommend to anyone looking for a new athletic competition to follow.

In most leagues and tournaments, beach volleyball games have a 3-set format, with each set finishing when a team reaches 21 points (or higher if they’re not yet ahead by 2). The third set (played if needed) will go up to 15 points (again, win by 2). Some leagues/tournaments will play all three sets up to 15. It depends on the venue, tournament, etc.

I rarely watch a match live, but I often pick up the live streams a few hours after they air or possibly in the following days or weeks. Even though I’m not watching the matches live, I don’t know who the winners are, so I like to go into each viewing and be surprised with the result.

Unfortunately, that’s often not possible due to YouTube’s video duration indicator on the thumbnail. Here’s an example of a match I watched this weekend:

Just looking at the video duration and the players involved, before I even watched the video, I was about 95% sure of the result. Why? Because the duration is 42:43.

I know that Andy Benesh and Miles Partain are the most dominant team on the tour right now. I also know that a single beach volleyball set usually takes about 20-30 minutes. Since this match’s sets end at 15 points, it’s definitely about 20 minutes per set.

Simply by looking at the video duration, I know two things before watching the video:

  • The match lasted only two sets
  • Whoever won the first set won the match

Thus, I’m almost positive the winners were Andy and Miles because of how unlikely it is that they lost in straight sets.

This means the only time I’m genuinely surprised at the result of a match is if the video duration is about 1 hour. Since the match is a best-of-three, the fact that someone wins set one won’t tell me anything about the result.

This is a clear example where the platform being used to broadcast the event is harming the user experience. Sure, it’s still fun to watch the matches — but it’s more fun to watch when you don’t know the result.

Adding to this, even in the case where a match is about one-hour in length, there’s the possibility that the ending is spoiled before it actually ends. For example, if I’m in minute 57 of a 1-hour video and Team A has match point and is ahead by 3 points, I know there’s not going to be a comeback from Team B. Due to the nature of volleyball, it is physically impossible for team Team B to score 5 or more points in less than 3 minutes.

That latter example is less concerning. It’s the thumbnail duration spoiler that is the bigger problem.

So what’s the solution? Yes, there are browser extensions that remove the progress indicator and duration, like this one. But that’s not going to help me when I do the bulk of my watching on mobile. I haven’t been able to find a setting or other way to change this on mobile (not to mention that they would have to remove the duration for all videos, including those in your recommended, subscriptions, etc).

There are a couple of ways to resolve or improve this problem:

  1. YouTube could automatically remove the duration indicator from video thumbnails for all livestreamed videos that are sports, games, etc. (this could also be an optional setting for the user or even for the channel that streamed the event).
  2. Events that livestream sports or games where the result can be strongly implied by the video duration could append empty livestream time to all their videos.

I don’t see YouTube changing this anytime soon, so option 2 is what I would do if I ran the AVP tour’s livestreaming production. I would leave the stream running for each game until the duration of the video reaches one hour or more (depending on the tournament). If all the AVP livestreamed videos were one hour in length or longer, that would disguise the game result and allow all viewers to experience the event as if it were live.

What I’ve described here is specific to volleyball, but a similar principle applies to all sorts of events where duration implies spoilers. Even older videos that were never livestreamed could benefit from the lack of duration and progress bar. For example, not everyone has seen the incredible and improbable 2011 World Series Game 6 in MLB. Time spoilers completely ruin a first viewing of that game, and I’m sure there are other examples.

The post YouTube’s Time-Based UX Problem for Live Sports appeared first on Impressive Webs.

View Details

We can all agree it’s ridiculous to suggest that we should ignore a modern tool that makes it exponentially easier to finish our work.

But as I’ve learned in 20+ years of writing code, there’s always going to be a drawback to using any tool that “makes life easier”. In this case, AI-based tools that use ChatGPT or some other AI-based foundation are similar to the frameworks we’ve been using for years.

There are developers who can build incredible websites with React, Angular, Vue, or Svelte. But many of those same developers couldn’t do basic DOM manipulation or build a simple Ajax-based website (or better yet, a Fetch API-based website) with pure JavaScript.

Now ChatGPT is everywhere, in almost any tool we use, ready to do all the work for us.

I can’t see this as being a good thing in the long run. I think two things can be true at once:

  • It’s productive to use AI-based tools to complete our work
  • It makes us dumber to use AI-based tools to complete our work

So here are my suggestions (meant for front-end developers, but the same concept applies elsewhere):

Every once in a while, when you’re not in a time constraint, write code using a blank slate. Don’t use a framework and don’t ask ChatGPT questions. Just write HTML, CSS, and JavaScript from scratch. If you don’t know how to do something, look it up online like you did back way back in 2021.

If you’re pretty sure of what feature to use (like Flexbox) but aren’t sure about how exactly to use it, look it up on MDN or another similar resource. Or find a nice tutorial that walks through all the features. I’ve done simple but interactive ones for CSS Grid and for Flexbox that you might enjoy.

When you write a piece of code, do your best to understand what every line — and even every character — is doing. If you change the code slightly, like changing a CSS value, ask yourself, Why does it break? Why does it not break? Endeavour to understand it. Don’t just move on because “it works”.

The same applies to JavaScript. MDN’s resource is, again, invaluable. So is Stack Overflow. I’ve been writing JavaScript tips in my newsletter since 2013. Every one of those tips can be found in the newsletter archives or (if you prefer) in an e-book bundle that discusses more than 300 different JavaScript and DOM features, most of which are lesser-known.

All this being said, it is true that ChatGPT itself can be used as a search engine or question/answer engine. But there’s something lacking when we go that route. The answers it gives are often too good and turn us into brainless robots who copy and paste the answers without much thought. And I’ve already had problems when using ChatGPT myself when it comes to debugging, maintaining, and updating code. It almost feels like you save time in the beginning, but lose a lot of that time later.

Ultimately, we’re all going to do what helps us finish our jobs, makes us more money, and pleases our bosses and clients. But let’s not forget about raw coding. That’s the kind of work that I believe makes us better web developers and will help us be capable in a job interview.

The post Don’t Let ChatGPT Write Your Code appeared first on Impressive Webs.

View Details

Over the last 10 years or so I've done a ton of technical editing work. I've helped with CSS articles and CSS books for various online and print publications. One of the things that comes up often when I make suggestions is the difference between a CSS rule and a CSS ruleset.

In most cases, almost all authors use the term "CSS rules" to refer to the blocks of CSS that include the selector and the CSS declarations. Is this correct?

The post CSS Rules vs. CSS Rulesets appeared first on Impressive Webs.

View Details

[Sponsored] If you’re building an app that requires a lot of user-generated content and media that needs to be processed, tagged, filtered, or otherwise manipulated in real-time, you definitely want a solution that’s fast and seamless and doesn’t get in the way of your app’s primary functionality. Filestack is a service you’ll want to consider. Here’s what Filestack offers:

The post Filestack: A File Uploader and Powerful APIs to Deliver and Transform App Content appeared first on Impressive Webs.

View Details

In 2022 I think it’s still important as a web developer to test your how your websites look and function when users disable JavaScript in their browser. Developing in this way used to be a cornerstone of Progressive Enhancement and can be handy on both desktop or mobile.

I still find myself wanting disabling JavaScript on pages I visit. Sometimes it’s to test a page I’m working on, but in other instances it’s simply to visit a web page that’s not functioning correctly and I want to see if JavaScript is the culprit.

The post How to Disable JavaScript in Almost Any Browser appeared first on Impressive Webs.

View Details

[Sponsored] If you’re building an app that requires delivering a dynamic experience based on the user’s location or other location-related data, a fast and easy-to-use Geolocation API will certainly come in handy. One such option is ipwhois.io. The service, which is free for small non-commercial projects that need fewer than 10,000 requests per month, is easy to integrate with your tech stack.

As usual, it’s always best to look at a few examples so you can see it in action. Their documentation is short and easy to follow, so I’ll demonstrate using the following example request:

The post A Review of ipwhois.io for Reliable Geolocation Data appeared first on Impressive Webs.

View Details

Recently I came across a CodePen demo by a developer/engineer named Jane that was Tweeted out by Šime Vidas. The demo has a neat collection of HTML and CSS tricks rolled into one that I thought was worth examining in detail.

The page displays a secret message based on specific text input. Ok, that’s no big deal, right? Well this is done using pure HTML and CSS – no JavaScript. I’ve seen stuff like this before, but I thought it would be cool to break down exactly how this works. There are a few notable things happening in the code so I’ll break down each of the parts.

The post Detecting Specific Text Input with HTML and CSS appeared first on Impressive Webs.

View Details

When I come to the end of any given year, it’s always interesting to look back through the click-through stats for my weekly newsletter Web Tools Weekly to see which tools got the most attention.

This year wasn’t all that different from previous years. I’ve learned that clicks happen for basically one of two reasons:

The post Are These the Most Interesting Front-end Developer Tools for 2021? appeared first on Impressive Webs.

View Details

When I visit a page, I get annoyed when I try to interact with elements while the website is still loading. Often stuff is moving around, fonts aren’t quite loaded, and it feels broken.

I know nowadays we’re obsessed in this industry with gaining every millisecond in page performance. But in a couple of projects that I recently overhauled, I added a subtle and clean loading mechanism that I think makes the experience nicer, even if it does ultimately slightly delay the time that the user is able to start interacting with my page.

The post Fading in a Page on Load with CSS & JavaScript appeared first on Impressive Webs.

View Details

A couple of months ago a post by Leo Blanchette got to the front page of Hacker News and there was an interesting discussion on dealing with broken links and external content – the main problem being links that become out of date due to paywalls, altered content, or content getting taken down.

I’ve been running this blog since May 2008. If you’ve run a content-driven site for even a fraction of that, you know that link rot is a problem. In this post I’ll go over some of the suggestions in that thread along with some tools to use to check for broken links.

The post Solutions and Tools for Dealing with Broken Links in Web Pages appeared first on Impressive Webs.

View Details

This week I did some research to try to build a hamburger menu that opens a slide-out navigation panel, a common design pattern nowadays. But I wanted to ensure the whole thing was keyboard-friendly and as accessible as possible.

I’m not 100% sure what I’ve come up with is the most accessible solution, but I did consult a number of decent sources on building accessible navigation menus like these. I also did some rudimentary testing using the free NVDA screen reader, to ensure there are no major problems.

The post Accessible and Keyboard-Friendly Hamburger Menu + Slide Out Navigation appeared first on Impressive Webs.

View Details

I’ve been coding websites for a long time but even I was a little puzzled when I came across a Hacker News comment where the commenter described their own makeshift CMS that involves using your own file system. The most interesting part to me was when the person said they add CSS to pages on their personal projects by means of HTTP headers.

I had heard of this technique before and the person does say in the comment that this doesn’t work in every browser. But I decided to do some research to figure out how one might do this and why this would be easier than just dropping in one or more <link> elements in the HTML.

The post Adding CSS to a Page via HTTP Headers appeared first on Impressive Webs.

View Details

Back in 2011, Paul Irish posted his personal list of frontend RSS feeds for front-end web developers. It was a great list, but after some time it needed some refreshing.

In 2014 I published my own list of categorized feeds for front-end developers. I cleaned up Paul's feed list quite a bit and added some new feeds, while splitting the feed up into manageable categories.

The post Front-end RSS Feeds (2020 Edition) appeared first on Impressive Webs.

View Details

Over on CSS-Tricks, Chris breaks down what some in the industry have said on the possibility that there will one day be a CSS4. The latest article that Chris references is one by a well-respected member of the community, Peter-Paul Koch (“PPK”).

In brief, PPK believes in initiating some sort of marketing gimmick wherein we basically try to repeat the success of the buzz surrounding “CSS3” by pushing the name “CSS4”.

Chris agrees:

I think he’s probably right. If we all got together on it, it could have a similar good-for-everybody bang the way CSS3 did.

I love Chris but I have to strongly disagree on this one!

The reason “CSS3” worked is because it was real. It was the successor to “CSS2.1”. Everything after CSS2.1 was considered to be under the umbrella of “CSS3”, and the things it included were really cool (as he points out in his post).

So although you can’t find a specific spec document that’s called “CSS3” like you can CSS2, CSS3 was still a sensible version of the language that had boundaries of what was in it and what wasn’t. And it was great for the industry that we had that little marketing boom.

But there’s no real way for us to do that with some imaginary “CSS4”. PPK is way off base on this one and I almost think he’s trolling us by recommending that. Whatever we try to push using the term “CSS4” will be fleeting and pointless and won’t do anything to contribute to the industry like PPK thinks. The irony is that the very fact that PPK is recommending this makes this a bad idea! It’s like a reverse-Streisand effect or something.

In his article PPK says:

I think that announcing a new CSS version will bring desperately-needed attention to CSS.

This is silly. CSS has the exact amount of attention it needs. It solves very specific problems and it does it well. Developers are excited about things that are really powerful. Like React, and Vue, and webpack, and Web Components, and CSS-in-JS libraries, and PWAs, and the list goes on. As for those that PPK refers to as the “torso” or “longtail” (the not-so-in-the-know developers), they too get excited about the tools I mentioned above – as long as those tools are marketed in a way that’s palatable to them.

PPK also says:

Web developers are profoundly influenced by the cult of the new.

Agreed. See the tools I mentioned in the previous paragraph. A superficial CSS4 isn’t going to excite anyone; we are in the midst of a whole new era of web development now and we already have many reasons to be excited about the industry. CSS4 won’t do anything to contribute to that.

Modules are the Better Way I think the way this has been done post-CSS3 is much more effective than how it was done before. Previously we were wondering “Does this browser support CSS3?” which is a ridiculous question today and was a ridiculous question then too. In his post, Chris tries to determine what should fall under “CSS4” and he can’t really do it, so that poses another obstacle in this. But with the module system, we can break things down and it makes sense when we say “Does this browser support Selectors Level 4?” or “Does this browser support Grid Layout?”

All this being said, if the W3C wants to start dividing a group of CSS modules into something officially referred to as “CSS4”, then they can try it out. But I don’t believe it will have the same effect that CSS3 had. The marketing around CSS3 evolved naturally. Any attempt to recreate that is just living in the past.

We’re much better off with a fragmented language of separate modules. When you think about it, the marketing pushes that have occurred around features like Flexbox and Grid Layout have been just as valuable as the overall marketing that took place for CSS3 before Flexbox was even a thing. And again, those marketing pushes happened naturally – nobody forced them on the industry. They were just the byproduct of an exciting new thing in web development – just like CSS3 was!

PPK further states:

When considering the pros and cons of CSS4, don’t reason from your own experience. Please put yourself in the shoes of someone whose time is limited, or who has never learned to pay a lot of attention to technical evangelisation. Will they be helped?

CSS4 is not going to improve tech evangelization. We already have effective tech evangelization when we push individual modules like Flexbox, Grid Layout, Selectors Level 4, and so on. What PPK is wishing for is already happening and it’s occurring in a more effective way than it would with “CSS4”.

So let’s keep doing what we’re doing and not try to force the industry to relive the past using a present superficiality. CSS4 isn’t a thing and shouldn’t ever be a thing. And it would be silly for us to try to push it as if it was.

The post CSS4 is a Bad Idea appeared first on Impressive Webs.

View Details

You are probably aware that ECMAScript has something called JavaScript Infinity, which is a numeric value that you can apply to any variable, the same way you can apply other numbers as values for variables.

Infinity of course is not the same as other numbers, so I thought I’d summarize, with examples, many of the quirks and useful facts around JavaScript Infinity and how it works.

What is Infinity? As mentioned, Infinity is a numeric value. Technically, Infinity is classified as a property of the Window object, similar to how variables in the global scope become properties of Window:

``` console.log(window.Infinity); // Infinity console.log(window.Infinity > 100); // true console.log(window.Infinity < 100); // false

```

  • Try it on CodePen

Despite this, Infinity is not writable, enumerable, or configurable. So you can’t use something like for...of with Infinity as the object:

``` // This won't work! // Uncaught TypeError: Infinity is not iterable for (let i of Infinity) { console.log(i); }

```

Which is not surprising because you can’t do that with any number; you can only do it with an iterable object. But you can use Infinity as the ceiling of a customary for loop:

``` // Don't do this! for (let i=0; i<Infinity; i++) { // Infinite loop }

```

Naturally, this creates an infinite loop and will either crash your browser or your browser will warn you that your script has an infinite loop and will attempt to escape it.

When is Infinity Returned? A calculation will return Infinity if the value returned is too high. That is, if it passes a certain threshold. You can find out more or less what that threshold is by typing numbers into the browser’s console until you get a return that equals Infinity, as shown in the following video.

Download MP4

In this case, I’ve typed a nine more than 300 times. It actually doesn’t seem to matter what digit I type, as long as it’s not all zeroes; once I hit 309 digits, the return will be Infinity.

A number like the one above can also be represented in scientific notation using the format 1e309. So, for example, if I were to set two variables to the values 1e308 and 1e309, respectively, you’ll notice how they differ when I try to log them to the console:

``` let bigNumber = 1e308, biggerNumber = 1e309;

console.log(bigNumber); // 1e+308 console.log(biggerNumber); // Infinity

```

Again, this just demonstrates the approximate threshold where Infinity starts to be returned. To be even more precise, according to the spec, Infinity represents all values greater than 1.7976931348623157e+308:

``` let largeNumber = 1.7976931348623157e+308, largerNumber = 1.7976931348623157e+309;

console.log(largeNumber); // 1.7976931348623157e+308 console.log(largerNumber); // Infinity

```

  • Try it on CodePen

Infinity will also be returned when a number is divided by zero:

``` console.log(46 / 0); // Infinity

```

This is not the same as what happens when you attempt this on a calculator, which usually will say something like “Cannot divide by zero” or a similar error message.

Another way to return Infinity is via a property of JavaScript’s Number object, as shown in the following code:

``` console.log(Number.POSITIVE_INFINITY); // Infinity

```

This constant isn’t very useful, however, because it can only be used in the form shown above, and can’t be used on a Number object you create yourself (although I’m not sure why you would want to do that anyhow).

Checking for Infinity Based on the constants mentioned in the previous section, you can check for Infinity using something like this:

``` function checkForInfinity (value) { return value === Number.POSITIVE_INFINITY; }

console.log(checkForInfinity(Infinity)); // true console.log(checkForInfinity(789)); // false console.log(checkForInfinity(1.7976931348623157e+308)); // false console.log(checkForInfinity(1.7976931348623157e+309)); // true ```

Here I’m simply comparing the passed in value to the Number.POSITIVE_INFINITY constant which always returns Infinity.

  • Try it on CodePen

On a related point, JavaScript has an isFinite() method that can be used to test if a value is finite (that is, it’s not equal to Infinity). This might be necessary if there are some calculations taking place where you suspect a dynamic value might get too large. Some basic logs demonstrate how isFinite() can be used:

``` console.log(isFinite(45)); // true console.log(isFinite(-45)); // true console.log(isFinite(Infinity)); // false console.log(isFinite(1.7976931348623157e+308)); // true console.log(isFinite(1.7976931348623157e+309)); // false

```

But care needs to be taken when using isFinite(), because it will coerce non-number values to numbers:

``` console.log(isFinite('45')); // true console.log(isFinite('-75')); // true

```

  • Try it on CodePen

So keep this in mind when using isFinite(). This method will return false for any non-number (e.g. a string that doesn’t coerce). So you may only want to use it if you know the value being checked could not possibly be anything but a finite or infinite number (i.e. it’s not a string or other type).

Infinity Can Be Positive or Negative Although Infinity is commonly viewed as a ‘big number’, it can also take on the role of the smallest possible number when represented as a negative. Below are some console tests to demonstrate.

First some standard greater-than and less-than tests:

``` console.log(Infinity > 100); // true console.log(Infinity < 100); // false

console.log(-Infinity > 100); // false console.log(-Infinity < -100); // true

```

Now I’ll compare positive Infinity to the highest possible non-Infinity value and negative Infinity to the lowest possible negative value that’s not negative Infinity:

``` console.log(Infinity > 1.7976931348623157e+308); // true console.log(-Infinity < -1.7976931348623157e+308); // true

```

And here I’ll confirm where the Infinity threshold begins in both positive and negative:

``` console.log(1.7976931348623157e+309); // Infinity console.log(-1.7976931348623157e+309); // -Infinity

```

  • Try it on CodePen

As you might guess, if you divide a negative number by zero, the return will be -Infinity:

``` console.log(-46 / 0); // -Infinity

```

You can also return -Infinity using the following property of the Number object, which is similar to the positive infinity property mentioned earlier:

``` console.log(Number.NEGATIVE_INFINITY); // -Infinity

```

Interestingly, Math.max() (which returns the largest of the passed in values) will return -Infinity if no values are passed in, and Math.min() (which returns the lowest of the passed in values) will return Infinity if no values are passed in.

``` console.log(Math.max()); // -Infinity console.log(Math.min()); // Infinity

```

  • Try it on CodePen

Infinity as a Default Value In his new book JavaScript for impatient programmers, Axel Rauschmayer has an interesting use case for Infinity as a default value. Since Infinity is larger than all numbers, it can be useful in a function that checks for the minimum number in an array:

``` function findMinimum(numbers) { let min = Infinity; for (const n of numbers) { if (n < min) min = n; } return min; }

console.log(findMinimum([20, 6, 90])); // 6

```

This works nicely because Infinity is greater than all numbers so unless all the numbers in the array cross the Infinity threshold, the result won’t have any problems.

  • Try it on CodePen

Beware of Infinity when Converting to JSON When dealing with JSON data, if you’re using JSON.stringify() to convert a JavaScript object to a valid JSON string, you should be aware how Infinity values are treated. Notice the following example:

``` let myJSON = { value1: 6, value2: 'Example Text', value3: Infinity, value4: -Infinity, value5: 1.7976931348623157e+309 };

console.log(JSON.stringify(myJSON, null, 2));

/ Result: "{ 'value1': 6, 'value2': 'Example Text', 'value3': null, 'value4': null, 'value5': null }" /

```

  • Try it on CodePen

Notice the original data in the JavaScript object, prior to being stringified, includes three different infinite values. When the data is actually stringified, however, those values are all converted to null. This would also happen if one of the values was initially NaN.

Conclusion So that’s just about everything I’ve learned about the JavaScript Infinity value. I hope some of this was interesting to you, even if you’ve been writing JavaScript for some time.

Did I miss anything or misstate something about the quirks of JavaScript Infinity? Feel free to let me know in the comments or on Twitter.

The post The Weird World of Infinity in JavaScript appeared first on Impressive Webs.