Christian Heilmann

You are currently browsing the archives for the General category.

Archive for the ‘General’ Category

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.

A Twitter eulogy and the complicated relationship with my X…

Thursday, December 26th, 2024

X isn’t Twitter. X isn’t even driven by human emotions any longer and is run by a management that doesn’t care about people, emotions or the dangers of propaganda. That’s why a lot of people who made Twitter grow in the beginning – real content creators – now meet on BlueSky. I do, too, but I still post on X. Here’s why…

Twitter beginnings…

When Twitter came out, I was not convinced. I’ve been blogging for a while and I’ve seen other short form content creation platforms come and go. I worked in Yahoo on Messenger and the front page and didn’t quite see the need for another way to tell the world a few sentences. The concept of Microblogging felt pointless.

What I liked about Twitter was the API and the platform idea. It was easy to build bots and you could access the platform via SMS, email, HTTP and many other ways.

I liked the whimsical and warm design of Twitter. You start as an egg avatar, the logo was inviting and I met a lot of lovely people who worked there. The food in the SF office was amazing when I visited them and it attracted good talent. I loved the fail whale and I really liked that things like were invented by the community and endorsed by the product.

I also liked that you could not only post and react but also message folks in direct messages. This is something I still cherish and use. I sourced a lot of speakers for events that way, I met interesting people, got help from companies and even chatted with some celebrities from great shows I like (Star Trek, Qi…).

Modest successes…

I always fluctuated in the 60-70k followers range and as some of them are journalists and other good multipliers, I got quite some reach. So much so that around 2008 some of my tweets took down websites because of a traffic spike.

One on ones > deluge of “news”…

I always only glanced at the feed and concentrated on replying to comments and DMs instead. I get my news elsewhere and I’m OK with that.

X now…

Fast forward to now, 2025. Twitter is X and it is a dumpster fire. It’s run by a megalomaniac man child who openly supports fascists and the algorithm favours tech bros and growth hackers to real content creators. Interaction bait is favoured by the platform. Real content creation pointing to online resources to verify or “read further” is seen as less useful.

Gone are the days of whimsy. It feels cold, automated and not a community but a bunch of “go getters” wanting to write the perfect engagement update. Keep them occupied, keep them emotional, keep them annoyed. Spread hate and lies, who cares as long as the numbers go up.

The amount of shits I give to the news feed of X is zero bordering on negative numbers.

The only interaction I do on accounts I don’t know personally is point out racist, sexist or utterly wrong posts. I sometimes answer with the right information backed up by a trustworthy resource. I sometimes flag posts as inappropriate, knowing full well that this is pretty much pointless against an army of bots endorsing them.

So why not leave X?

I know that people appreciate my resources here, so I will keep pushing out to Twitter. I’ll also answer your DMs but I moved my reading and commenting to other platforms like LinkedIn, Mastodon and BlueSky. The latter really feels good right now. X does not. However, me leaving in a huff wouldn’t mean anything to the machine, except one more moderate voice gone.

I still stay because of my followers and some good DMs that still happen. The other part is that by adding content that’s not horseshit I might still play a small part in allowing people to find value.

X is a big bullhorn to the world and if we only let the horrible people shout into it, we shouldn’t be surprised if things go down the drain.

If people in a pub or train carriage shout racist, sexist or other hurtful things, I interfere and point out that it isn’t tolerated here. This takes courage, but it is incredibly important. Online we should do the same. Just because terrible people are successful doesn’t mean they are right.

Stupid interview questions will get you limited developers – is that what the market wants?

Monday, December 23rd, 2024

In recent times a meme has been making the rounds that allegedly shows a smart way to solve interview puzzles. In these memes developers are asked to create an ASCII pattern like the following:

XXXXXXX
XX   XX
X X X X
X  X  X
X X X X
XX   XX
XXXXXXX

The solution they come up with is a simple console.log() or print command.

console.log(`XXXXXXX
XX   XX
X X X X
X  X  X
X X X X
XX   XX
XXXXXXX`)

Funny, of sorts, and it shows how limited interview questions like these are. Ask a stupid question, get a simple answer.

That’s why in CODE100 puzzles, I always used tons of data or asked people to create a pattern from a dataset. I make it annoying to type these things by hand – or provide erroneous examples – so that people have to start thinking.

Programming is about flexibility and preparation for change, not instant creation

This, to me, has always been the idea of programming: provide a flexible solution for a problem. Instead of “create this thing”, my first goal is always to “create a solution that can create this thing, but also derivates of it”.

I suppose being a web developer teaches you that from the get-go. As you have no idea what text or in what language you need to show content in CMS driven products, you create flexible solutions. There is no such thing as “This button is always one word, and not more than 10 characters”. So you make the layout grow and shrink with the need and the capability of the display device.

And in general this should be a thing to get used to as a developer: requirements will always change. No matter how detailed a specification is. No matter how accomplished the prototype looks. There will always be new things coming your way. That’s why the first reflex of a developer to a request like this should always be this:

“How can this change in the future, and what do I need to put in my code to be ready for it?”

Or, to put it in other words:

“This is one outcome, but how can I create something that creates this one, but also more generic ones?”

My solution to this would be to create a generic grid I can plot on. One way to do that is creating an array of Y values with each having an array of X values.

class ASCIIgrid {
  grid = [];
  create = (width, height, char) => {
    for (let i = 0; i < height; i++) {
      this.grid.push(Array(width).fill(char));
    }
  };
  plot = (x, y, char) => {
    if (y >= 0 && y < this.grid.length && 
        x >= 0 && x < this.grid[y].length) {
      this.grid[y][x] = char;
    }
  };
  render = () => {
    this.grid = this.grid.map(row => row.join(''));
    return this.grid.join('\n');
  };
}

This allows for a plot method to set a char at x and y, and a render method that returns the nested arrays as a string.

That way I can “paint” the solution and many others:

import { ASCIIgrid } from './index.js';
let c = new ASCIIgrid();
let w = 7;
let h = 7;
let char = 'X';
c.create(w, h, ' ');
for(let i = 0; i < h; i++) {
    c.plot(i, 0, char); // top line
    c.plot((w - 1), i, char); // right line
    c.plot(i, (h - 1), char); // bottom line
    c.plot(0, i, char); // left line
    c.plot(i, i, char); // downward left to right
    c.plot(i, (h - 1) - i, char); // downward right to left
}
console.log(c.render());

Overkill? Maybe, but I could now easily create the same pattern for 9 chars, 27 chars or 101 simply by changing the w and h variables. I could also just paint an X, a smiley, a sine wave, or whatever. I don’t expect someone in an interview to write this code, but I would love to see the same thinking in people when I ask a question like that. As a good developer, I am lazy. I create code that will be ready for future requests as well as the immediate problem. Or is that too much?

Do we need developers that think ahead?

Which brings me to the problem interview questions like these hint at. My approach comes from years of frustration of changing requirements. And I almost never got enough time to clean up my solutions. That’s why I padded my estimates so I have time to code what’s needed, and not what brings the immediate result. I plan on building products that last and change over time, with a solid, working core. But is this still even a thing our market wants?

Is software a disposable product?

Over the recent years, software has become a disposable product. Instead of software solutions, we built apps. Packaged and released solutions controlled by the software publisher. New features or fixes required a re-publication and upgrade by the end user. That was not what the web was about. Web products get new features without a need to upgrade, uninstall or re-install. The problem with that is that I can’t control the user as much as publishers want to, so we went the way of apps. We made the web a distribution platform for things our end users have no control over.

Nowadays apps are disposable. You can have them automatically generated by frameworks or even using AI and a prompt. Many tools allow you to create a design and generate code that makes the app work. But, the code makes this snapshot app work. It is not code that functions beyond the visual. And it is code not fit to take care of changes that might happen in the nearer future. Changes that will always come as user needs and environments change over time. I don’t know about you, but this all feels incredibly wasteful to me. Programming, to me, is about flexibility and reaction to change. Not to create a product akin to a physical thing I use and discard once its not serving the original purpose any longer.

Maybe my way of thinking is outdated, and not necessary any more and I put too much stake into creating generic, expandable code. But, as developers we shouldn’t be surprised that AI and code generation can take our jobs if all we do is “build this thing” and not “find a solution to this problem”.

A behind the scenes of how I create an edition of the WeAreDevelopers Dev Digest – 3 hours in 1 minute speedrun

Wednesday, December 4th, 2024

I write a newsletter every week at https://wearedevelopers.com/newsletter with 150k subscribers. Today I recorded the 3 hours I spent putting the current edition together. Here it is sped up to one minute. I use my browser, lots of copy + paste and VS Code.