Christian Heilmann

You are currently browsing the Christian Heilmann blog archives for January, 2025.

Archive for January, 2025

“modern” is rubbish

Tuesday, January 21st, 2025

Charlie Chaplin in the movie modern times riding a big cog and tightening some nuts.

Some terms irk me whenever I read them and one of them is “modern”. I try to avoid it like the plague, which is counter to all the marketing announcements you read out there:

  • “Product X uses modern JavaScript features”
  • “7 modern CSS tricks you can’t live without”
  • “The modern productivity tool to get your engineers to burn out and loving it”
  • “342 modern templates to make your web app stand out”

Modern does not mean much. And it is not a sign of quality. All it says it that something is created according to a current trend or fashion and doesn’t do what has been done earlier. That doesn’t mean it is better, it just means that it does things differently.

Modern, like any fashion, is fleeting and doesn’t stand the test of time. You could do a search and find thousands of articles touting “modern ways” of doing things that now are dangerous, counter-productive or even unnecessary.

In order to see if a “modern” solution makes sense to apply, you need to check its publication date. And even then “modern” may also mean “trying to simulate what other solutions do” or “not quite ready for production yet”.

So here is my proposal. Every time we use “modern”, which implies “better than the old”, we can use “current” and the date shows its worth.

And this is why I don’t work in marketing.

Learning HTML is the best investment I ever did

Wednesday, January 15th, 2025

One of the running jokes and/or discussion I am sick and tired of is people belittling HTML. Yes, HTML is not a programming language. No, HTML should not just be a compilation target. Learning HTML is a solid investment and not hard to do.

I am not alone in this, Wired had a piece on HTML being a programming language and even for RAG training HTML makes a lot more sense than text.

HTML structures our content, makes it easier to index and gives us tons of accessible and easy to use interface elements. And it is straight forward to learn. The syntax is clear and the rules are only a few. And yet, nobody seems to even bother to look those up.

In last week’s Bytes newsletter there was a “spot the bug” challenge that looked like this:

<main>
  <form onsubmit="handleSubmit(event)">
    <fieldset>
      <label for="name">Name:</label>
      <input type="text" name="name" value="Tyler"  />
      <label for="age">Age:</label>
      <input type="number" name="age" value="33" />
      <button>Submit</button>
    </fieldset>
 
  <hr />
 
  <form onsubmit="handleSubmit(event)">
    <fieldset>
      <label for="company">Company:</label>
      <input type="text" name="company" value="ui.dev"  />
      <label for="employees">Employees:</label>
      <input type="number" name="employees" value="33" />
      <button>Submit</button>
    </fieldset>
  </form>
 
  <script>
    function handleSubmit(event) {
      event.preventDefault();
      const formData = new FormData(event.target);
      alert([...formData.entries()]);
    }
  </script>
</main>

The bug described was that as the first form wasn’t closed, the script got the wrong content. But there is so much more in this small amount of HTML that is wrong, it made me flinch.

Fieldsets need legends

It uses fieldsets without legends – why? The idea of a fieldset is to to group form elements and give that group a name. If you omit the name, all you did was paint a hard to style border around them.

Pointless labels

It uses labels, which is a happy surprise, but fails to connect them to the right form elements. For a label to describe a form element, you need the element to connect to an ID, not a name. A name attribute is not unique, instead it clusters form elements together. So, you could have a few elements with the same name, but you need to have an ID on each to connect it to the label. When the form gets submitted, the names become form data (or URL parameters), the IDs are there for HTML parser internal use. And more. IDs are the few multi-dimensional things on the web, as they can be accessed via the browser (hash at the end of the URL), they connect HTML elements together (a link pointing to it, or a label with `for`), they are easy to use in CSS and in DOM scripting. One weird thing is that every element with an ID also becomes a global JavaScript hook on the window. This is a convenience method of browsers, not a standard though.

A great example of this is a radio group. I hardly see those in use, but they are a great way to offer a “pick one of many” interface without needing any JavaScript.

Check this Codepen to see a radio group in action.

  <fieldset>
    <legend>Record Label</legend>
    <p><input name="recordlabel" type="radio" value="Trojan" id="company1">
    <label for="company1">Trojan</label></p>
    <p><input name="recordlabel" type="radio" value="Epitaph" id="company2">
    <label for="company2">Epitaph</label></p>
    <p><input name="recordlabel" type="radio" value="Hellcat" id="company3">
    <label for="company3">Hellcat</label></p>
    <!-- … -->
  </fieldset>

Notice that the name of the `ID` can be random, but needs to be unique, whereas the `name` makes sense to be human readable. This is even part of the spec :

Identifiers are opaque strings. Particular meanings should not be derived from the value of the id attribute.

As an extra, activate the `Toggle checkbox/radio` button to see that simply by changing the `type` attribute of an HTML input, you can allow users to either submit one or several values. By using properly connected labels, we also allow users to click/tap/hit space on the whole text to select instead of having to hit the small radio control.

Demo showing the difference between radio buttons and checkboxes allowing for one or several choices

HTML was and is fun!

HTML is – dare I say it – fun to me. The reason is that I started a long time ago. Building my first web site instead of creating things with Visual Basic or C builder was amazing. HTML appeared to me all powerful. I didn’t have to spend any money, install and understand a development environment. All it needed was an index.html file and writing the code using a text editor that came with the OS. I went to htmlhelp.com and downloaded the HTML spec as a zip and put it on a floppy to look things up. I was only online at work, my home internet connection came a lot later.

Unforgiving browsers

In the early days, making HTML mistakes was a problem as browsers would punish you for it. Netscape would not render tables that weren’t closed. And back then tables was the only way to create complex layouts. This was a bad use of HTML as it was non-semantic, but we had nothing else.

Later, when CSS became a thing there was still a lot of interference of HTML in the final product. Whitespace should not make a difference in HTML but it caused a lot of extra space in table cells and with images. The best advice I would give to designers back then that banged their head on the desk was to validate their HTML. The HTML Validator became my power tool to fixing issues for clients.

These days, HTML gathers less interest as with the HTML5 parser, things became a lot more lenient.

A lack of HTML interest and respect

As browsers bend over backwards to fix broken HTML, developers stopped caring about it. If it doesn’t break the build, it’s less important than getting those JavaScript packages bundled. But this, to me, is lazy development. Why rely on a platform to fix bugs that we could avoid if we put in a tiny bit of effort?

HTML has some exciting new features for us in 2025. A single element could replace a whole component library. Sure, the component might give us more predictable styling and more control. But it also is one more dependency, and could be a security, performance and maintenance issue. An issue we can’t fix as we don’t control it.

No matter how you create things for the web, the end product will be HTML. Either HTML generated on the server or with JavaScript. With AI search bots not rendering JavaScript yet maybe this is a good time to re-learn what HTML can do for you. It has not let me down in over 25 years, whereas lots of other “magical solutions” did.

trimMiddle() – the missing String trim method

Friday, January 3rd, 2025

One of the cool features of MacOS’ Finder app is that it does not trim file names that don’t fit the space at the end, but in the middle of the file name. This does make a lot more sense, as it also shows what format the file is.

MacOS finder showing long filenames with an ellipsis in the middle of them.

Neither JavaScript nor CSS have a method for that kind of functionality at the moment (although there is a CSS discussion on the matter), so I thought I write one. I give you `trimMiddle()` as an addition to trimStart and trimEnd .

You can find it:

On NPM: https://www.npmjs.com/package/trimmiddle
On GitHub: https://github.com/codepo8/trimMiddle

and you can play with the demo page to see it in action:

The test page showing the method in action

To use it in your own products, either use npm -​i trimmiddle or use the client-side version via unpkg .

<script src="https://unpkg.com/trimmiddle@0.1.0/clientside.js"></script>

The method allows you to define the amount of letters you want to show and what the character in between the parts should be. Default is 16 characters and the ellipsis character. The script uses the Intl.Segmenter API when the string is longer than the character limit, which means that it also works with strings containing compound Emoji. The normal split or substring methods fail in this case.