Hacker News new | past | comments | ask | show | jobs | submit login
A collection of bad practices in HTML (htmhell.dev)
160 points by pcr910303 33 days ago | hide | past | web | favorite | 87 comments



I feel like Bootstrap (and similar) are a lot "to blame" for some of these.

People have been using HTML tags non-semantically for a very long time and, to be honest, before HTML 4 you often didn't have a lot of choice in the matter.

Still, when I was getting back into web development in 2013 I became aware of an "I can just use <div> and <a> for everything, and then stick Bootstrap classes and event handlers on to get it to look and behave the way I want" attitude that had become pervasive amongst developers.

Now, to be fair, at the time this was legitimate: in 2013 older versions of Internet Explorer were still quite prevalent. They didn't support newer HTML5 constructs, or proper styling of certain elements. The <div>/<a> approach was often the only way to get things to look good, or even to look the same, across all browsers.

Those days are long since gone (for most of us, anyway[1]), but I wonder if the reason we continue to see this style of HTML is that we're still living in a sort of post-IE hangover period? Old habits die hard[2].

[1] I'm aware that even now not everybody has the luxury of pretending that IE doesn't, and never did, exist.

[2] Again, reminds me of the migration from earlier versions of HTML, where you'd really had to do things like use tables for layout and use various HTML elements for styling (with variable cross-browser support), to HTML 4, where you nominally didn't (except, of course, that not all browsers were created equal).


When i started working web IE6 was still far far in the future, i also learned the semantic use of html JADAJADAJADA table-layouts bad JADAJADAJADA and i most of the time enforced myself to apply this 'best'-practices - truth is - i never saw this providing value in any kind. The web is so full of shit and abuse of 'best'-practices - nothing will every really on this and work. I would often have saved myself and my clients a lot of headaches/time and money if i had just used table-layouts instead of css-layouts and other crap - but hey whatever 'float's your boat.


I believe you mean "yada yada" instead of jadajada?

https://www.merriam-webster.com/dictionary/yada%20yada


Perhaps in their native language a J is sometimes/always pronounced like an English Y.


Why are people down-voting an honest and helpful suggestion?


Anglo-splaining.


Can we stop producing the -splaining words and roll back the ones already shipped.


"helpful"?


I would consider correcting someone politely as being helpful. We are all here to learn.


thanks, captain :)


The benefit is for people who need assistive technologies to browse the web. If you don’t know anyone who needs assistive technologies, then of course you wouldn’t see the benefit.


Nope... how would someone have used (with assistant technology) the web back in the day if that would break it. You have to do some extra work for a good user experience, for these users anyway - so i don't take this as an argument ( as i said - if a screen-reader or other tools would fully relay on html-semantics to work - it wouldn't work).


> Nope... how would someone have used (with assistant technology) the web back in the day if that would break it.

This is begging the question! You start with the assumption that assistive technologies can handle table-based layouts well, and then work backwards from the conclusion that you’re trying to prove.

It may shock or surprise you, then, to learn that in actual fact, table-based layouts caused problems for screen readers (and still do, if I am not mistaken). There are a number of other ways that websites break screen readers, and the difference today is that (1) table-based layouts are hardly necessary or even popular these days and (2) more people are suing over ADA violations for inaccessible web pages.

The screen-reader tools do not fully rely on HTML semantics, but they do need some logic to differentiate between tabular content and purely presentational <table>. The reason for this should be fairly obvious once you look at any actual web page—when you navigate tables, you want to go by columns and rows, but if you are reading a table used for layout, you probably just want to flatten it and go through the entire thing in linear order (more or less). The process can be disorienting for people with screen readers if your site is poorly designed.

Of course, if you just make assumptions and guess about how screen readers and assistive technologies work, there is a good chance that your guesses are wrong.


Well, i don't use table layouts knowadays too - i didn't go into details about screen-readers, as the styles i usally apply for those are more similar to the printing stylesheets, hiding most design-elements -displaying the content more in a document-format, adding special screen-reader navigation, like goto-navigation/content etc. created a website for a 'disabled home' ( is this correct word ) - which was mostly used by the patients there, had some vision impaired ( not fully blind i think), but mostly spastics using various input-methodes ( keyboard, joysticks and some software ) and it seemed to work pretty good. What i meant in my first comment was purly targeted at the semantic meaning of html-elements.


"JADAJADAJADA"?


> I feel like Bootstrap (and similar) are a lot "to blame" for some of these.

IMO, it's more about developers just using Bootstrap without reading the documentation. The examples are pretty well done, they use semantic elements and are accessible.

For example, the Navbar[1] element has a good HTML structure and uses `aria-label`s that announces what's going on to assistive technologies.

Another one is the modal example[2], it has semantic elements, the `tabindex="-1"` attribute to make it accessible to keyboards and the correct use of the `aria-label` as well.

So, their documentation pretty much teaches you how to use it correctly. I'm not a fan of Bootstrap myself, but I think throwing the blame at it is unfair.

[1] https://getbootstrap.com/docs/4.3/components/navbar/

[2] https://getbootstrap.com/docs/4.3/components/modal/


That shift happened in bootstrap 4, bootstrap 3 was <div class="..."> everywhere. Also 3 was when bootstap was really big.

Good to see they improved, i guess :-)


That shift happened in Bootstrap 3's lifetime. The 3.4.1 navbar markup [1] and 3.3.7 navbar markup [2] is very similar to 4.x, but most of the semantic stuff and ARIA stuff is missing in 2.3.2 [3].

(I probably paid a lot more attention in 3.x documentation than most because of the mistake in a past life of forking Bootstrap 3 for an enterprise project and trying to keep it in sync with upstream. Never again would I consider doing that.)

[1] https://getbootstrap.com/docs/3.4/components/#navbar

[2] https://getbootstrap.com/docs/3.3/components/#navbar

[3] https://getbootstrap.com/2.3.2/components.html#navbar


> They didn't support newer HTML5 constructs

I am pretty sure at least as old as IE6 it was really simple to enable the newer HTML5 constructs via JavaScript (leading to small libs like HTML Shiv). Just a couple lines of JS to tell the browsers the element(s) exist, via document.createElement("blah") enabled the elements and allowed styling.


Oh my... HTML Shiv ( These are the old days man, the bad days, the all-or-nothing days. Marv ) - as far as i remember i still prefered to not relay on js back then - browser support/broken implementations where just spoty/common - also lot's of users/browsers would have js disabled. Only for using an attribute-selector in your css ( which you shouldn't if possible ) i thought that was to much overhead


That's true, but these polyfills weren't necessarily perfect. E.g., IE7 or 8 (I forget exactly which version - it's a long time ago) not supporting rounded corners on buttons.


#11 Giving a numbered list that has no ranking meaning and showing things in reverse order

#10 Making a simple webpage with 9 things on it and spanning it across two pages instead of just letting people scroll.


Haha yes, some of the examples aren't that bad so it's quite fair to cast a few stones back in that direction I think


To be fair for #11, it appears to be a blog, so that kinda makes sense. But with only 9 entries, it's a bit odd. No excuse for #10 though!


Is this pattern for SEO generation? So many sites take this approach - I'll be preaching to the choir complaining about how frustrating that user experience is.

While I'm ranting about web experience, how about Bitbucket hijacking the normal behaviour of ctrl-f in pull requests? Just.. why?!


No, it's typical behaviour for blog-type software: X numbers of entries per page; no allowance made for the length of each entry. Five novels on page one, four sentence fragments and a limerick on page two, etc.


Very good.


I sympathise with people using HTML "incorrectly" because there's a mismatch between how HTML is designed and what it actually has to do in the wild.

Maybe using the "correct" element structure is going to be much more complex in a given situation due to the fact that you've got CSS rules that will be in scope that will style it for another purpose, and you'll have to undo and override all that work bit by bit to get it to match what the designer envisaged in this particular placement.

So instead you just use some divs, stick a few generic classes on stuff and get on with your day.

The tools are supposed to be the slave of the workman, not the other way round.

I'm not saying that all of these are examples of this situation of course!


Indeed. HTML was designed as simple vocabulary for casual hierarchically structured documents in academia with anchor links and, later, forms. Then it was used for all kinds of online documents and apps as they evolved. To say that the HTML vocabulary hasn't exactly kept pace is an understatement IMO. What has evolved is bolted-on tech such as CSS and JavaScript, and as soon as that happened, HTML evolution was kindof doomed because changes to HTML weren't essential (could be implemented in an ad-hoc way once a Turing-complete language was in the mix).

Today, people praise CSS Flexbox and Grid, and they're no doubt a step-up from a practical PoV. But what has really just happened is that another ad-hoc syntax was introduced as a replacement for what previously went into HTML attributes, and worse, a syntax that needed to be able to roundtrip through HTML attributes via quoting and escaping. The notion of "semantic" markup and the HTML-CSS-JS trinity is really an after-the-fact rationalization of this syntax soup accident. From a comp.sci. PoV, there is no rationality and progress in piling up syntaxes over syntaxes with identical purposes, nor in equipping CSS with the power to rearrange element order, insert content, and whatnot, especially since HTML always had adequate typing based on a formal ISO standard (using SGML) whereas CSS lacks this completely.


I've only looked at web components casually, but the examples I saw seemed a greater mess than this. Interact DOM components, CSS, slots, JS, private DOM, ... AND plan for late-loading code and resources. ?!


Sigh. Basically you want to disregard web standards that have a purpose to be able to "stick generic classes."

> there's a mismatch between how HTML is designed and what it actually has to do in the wild.

There is an entire HTML spec[1] that explains what specific elements are for. And I agree that is not perfect, but this is what we have and if we at least don't follow it, we will be building even more shitty websites.

> Maybe using the "correct" element structure is going to be much more complex in a given situation due to the fact that you've got CSS rules that will be in scope that will style it for another purpose, and you'll have to undo and override all that work bit by bit to get it to match what the designer envisaged in this particular placement.

> So instead you just use some divs, stick a few generic classes on stuff and get on with your day.

Some "web developers" want to use `div`s instead of `button`s because it takes less CSS to style the former, but what they don't realize is that they are making theirs (the "developer") life easier, but are giving a bad UX to people that use assistive technologies and someone else, guess who? Search engines!

Search engines are basically blind entities that only use the keyboard. So, if you use a `div` they will see it as a `div`, they won't see the bunch of classes you added to make it look like a button.

So, it's a better good experience and search engine optimization to use semantic HTML. This means if you need a button use a `button`, if you need a link use an `a`, if you need an image that when you click on it it will take you to another page, surround the `img` with an `a` tag and use `aria-label` to announce what clicking on that link will do for the user, e.g.,

  <a href="/learn-semantic-html" aria-title="Visit the learn semantic HTML page">
    <img src="/img/surprised-pikachu.jpg" alt="Surprised Pikachu meme">
  </a>
> The tools are supposed to be the slave of the workman, not the other way round.

A good craftsman knows its tools and the best way to use them because each one of them has a purpose. You shouldn't use a screwdriver to hit a nail.

[1] https://html.spec.whatwg.org/


I agree with everything you've said here, but I think we should understand why it happens and build a better solution to it rather than lamenting the fact that people will always try and avoid doing difficult things when those things should be easy.

We have a situation where these "correct" elements have different sets of default styles in different browsers and require different sets of styling rules to make them look how the designer wishes in each.

If your starting point is that is it any wonder that sites are generally so shitty? A good starting point would be true separation between the semantic and the visual.


These are all really bad. But when my designer designs links as buttons and buttons as links, which am I supposed to use? Then there's the redesigning pages, layouts and widgets every other week, based on our trackers and heat maps. How can I care about the quality of my html, when I know it's all gonna be scrapped next week or month when a new redesign comes in?


In practice the dichotomy between hyperlink and button is blurry and should be treated as blurry and interchangeable. But HTML doesn't really allow one to blur properly, at least not in all browser brands.

To resolve this, it should be easier to make hyperlinks into buttons and buttons into hyperlinks. The difference should be aesthetics only. They are both a "span with an action". The action and styling (button versus hyperlink) should be attribute-based. Examples:

   <action type="post" look="link">Action 1</action>
   <action type="post" look="button">Action 2</action>
   <action type="link" look="button">Action 3</action>
   <action type="none" look="link" onclick="myJS()">Action 4</action>


If it leads to a semantically different page, use <a>, if it's used only for javascript-interactivity use <button>. Never use <div> for buttons or links.


Is adding role=button to <a> enough, or should I style a button to look like a link (.btn-link in bootstrap)? One issue with .btn-link is getting the vertical alignment to match any surrounding text.


#9 https://www.htmhell.dev/9-cookie-consent-from-hell/ is missing good code. A cookie consent where the only option is OK give zero value. If you don't track users there is no need for the dialog and if you track the users this dialog do not show that tracking is turned off to you click OK


True, but cookie consent is pretty much entirely about following regulations, not about anti-asshole design.


Whilst that's true, the point of this example is how to put up a well-behaved modal, rather than how to comply with GDPR (or similar legislation).


This would be more interesting with descriptions of WHY it's bad, and a little bit of moderation.

As of this comment, there are 9 entries, and more than half have to do with similar link/button behavior (#8, #5, #4, #2, #1... and also kind of #3).

Some of these are also semantically invalid (e.g., #7). That's less a "bad practice" and more "invalid HTML".


They do have descriptions, the titles are are links to those.


So they do! Very good content hidden behind those links.


It feels like if your goal here was to improve the web you'd go into some explanation of why these are bad practices and how it can be done better.


I've added "read more" links to make it more obvious that there's more!

https://www.htmhell.dev/


Awesome!! Thanks


Click on each one and you’ll find an explanation


I feel like there's something poetic about a site complaining that people do HTML "wrong" having terrible UX.


It's not terrible UX. Whilst the headings aren't blue, they are underlined, which makes it pretty clear they're links.

I don't love hyperlinks in headings, and would prefer a more explicit link to each good example, tabs for good and bad, or even inline content to show the good examples below the bad, but it's a bit strong to be calling it "terrible".

Nowadays people are pretty slack about links: good UX generally mandates either a different colour to body text, or underlining, or both.

Blue has for many years been the default rather than the standard: people have been heavily deviating from it since the 90s. Underlining tends to be optional if there's some other way of distinguishing links (here there isn't).


I stumbled onto that by accidentally, really needs more context.


You could almost add "Hiding links via styling" to the list, but I feel like this site gets away with it; even though they're not blue, it's still pretty obvious those headers are links.


How about destroying a whole table and rebuilding it each time a checkbox loses focus? I've spent nearly a month debugging that one. Also, why create one table when you can create two overlapping ones? (it was a jQuery plugin, and a vendored one at that).


Linus would have said, your expectations are not user experience.

If I want my images to execute on click events, and so on, I probably have a reason for that. If that thing looks and works horrible, I'll learn that, but it may also work perfectly, or in 99% nobody cares.


That 1% matters when you're running a large, commercial website. Look what happened to Domino's recently. Sued for having an inaccessible website. Also, refusing coupon codes over the phone since a user couldn't use your website because you ignored accessibility guidelines is in completely poor taste. You want a discount? Better have vision that at least this good and fine-grained motor control necessary for mouse usage to successfully complete placing an online order.


> If I want my images to execute on click events, and so on, I probably have a reason for that. If that thing looks and works horrible, I'll learn that, but it may also work perfectly, or in 99% nobody cares.

There's a semantic way to accomplish that. If the click event you want to add triggers an action inside the page you can do

  <button aria-title="Open modal">
    <img src="/img/surprised-pikachu.jpg" alt="Surprised Pikachu meme">
  </button>
Or if clicking in the image takes you to a different page, then

  <a href="#" aria-title="Visit the learn semantic HTML page">
    <img src="/img/surprised-pikachu.jpg" alt="Surprised Pikachu meme">
  </a>
Then you can add your click event to the surrounding element and add a few classes to remove the default stylings.


Who cares about the "Check Engine" light as long as the car drives, right? After all, as long as it works, you probably have a good reason for ignoring it, for starters, going from A to B instead of paying maintenance and waiting.

... only eventually, a quick fix will have morphed into a destroyed engine.


That's horribly out of context. Pretty much every item in this list is unnoticeable to anyone but a developer. Leaving them where they lie wont cause your website to explode or stop running. In fact, I can't recall one, that the average user would notice.


Using links instead of buttons makes accessibility to screen readers worse.

Just because you can't see it doesn't mean it doesn't have an effect


Plus, just being aware of how these elements interact with screen readers, and what you need to do for them and keyboard users can make you more aware to write better, more accessible HTML in the future.

It’s a bit strange to me that in my last position all these great JavaScript engineers were still using div’s for everything when there’s so much you can harness directly from the browser’s interpretation of these elements to give you a pleasant and consistent user experience for your clients.

Besides that, it makes trawling through your elements in your web inspectors a lot easier to read when you actually have lists, sections, headers, buttons, etc.


Is that going to make your site explode? No. That was the premise of the comment, not that it doesn't have any effect what-so-ever.


For the button wrapped in a link example [0], which is invalid HTML, many people don't know it's valid to wrap a button inside a form, using the form's action as the destination. Not something I use often, but it's at least a thing worth knowing.

<form action="link.html" method="get" target="_blank"> <button type="submit">Link</button> </form>

[0] https://www.htmhell.dev/4-link-also-button/


I find that different browser brands react differently putting BUTTON tags inside of forms. Tread with caution. Internet Explorer versions are usually the biggest bottlenecks.


I often found that stressing about "semantic html" and the "correct way" is just virtue signaling and in reality, in real projects, if it works it works, and you move on.


> I often found that stressing about "semantic html" and the "correct way" is just virtue signaling and in reality, in real projects, if it works it works, and you move on.

On the other hand, I have found that most of the time the "I don't care, it works for me" people are just lazy or incompetent. Others mentioned blocking your site for screenreaders and ethical scrapers, I can add non standard (mobile) browsers to the list.

You might say you don't care about them. I say that is the same as throwing your household waste over the fence and let others fix it. It doesn't exist if you can't see it! The web as a whole becomes more inaccessible, it fortifies existing monopolies and mono culture.

It does not have to be perfect, you don't have to spend days. A little effort and awareness goes a long way.


If "it works" means "it also works for people with screen readers, people reliant on the keyboard, and makes use of the easiest input methods on phones", then I might be inclined to agree with you - although in practice, your HTML will probably be pretty "semantic", or it will have been more work to author than needed.


If you're working on projects of a certain scale, it becomes a legal issue. If it's personal site you're talking about, or a small client, then practically I could agree. But there's no reason to ignore accessibility guidelines if you're aware of them. I like to use tab navigation since sometimes it's faster than a mouse. But if you make your button a div, and don't add tabIndex="0" to that div, I can't do that. Your comment is too presumptuous about how people actually use computers.


I'm designing a program that deals with money. $25.99 looks like a floating point number, so I should use those, right?

\s


Actually no if your building a site to be searched you want to reserve h1, h2, and <table> for their sematic use.

H1 for main page heading h2's for sub headings and <tables for tabular data eg a list of ingredients or technical data

One use I have seen for table of the basic details of a yacht, displacement, speed , length etc


> in reality, in real projects, if it works, it works, and you move on.

This is your perception, but if you don't use semantic HTML, you are building elements that look like something (for sighted users) but in reality, is something else (for assistive technologies and search engines).

So, it only works for a part of your users. And maybe it works for the majority of your users, but that means that you are making it hard for people that use assistive technologies and search engines to navigate your site.

Leave alone people with disabilities because you don't seem to care. Search engines need semantic HTML to crawl correctly your website, so it's an important part of any project.


I’m curious if you think that best practices in all instances are just bologna?

It’s also interesting because certainly you must have come across those engineers and developers who’re so well versed in their particular portion of the field that they know to tweak VM settings for memory leaks, or how to shard databases for faster queries, or why your Z-index isn’t working.

Those people most likely spent time studying their crafts and learning the “correct way” to do things.


This is legitimately a dangerous practise. You are closing off your website from blind people and ethical web scrapers when you do this.


Closing off your website from blind people and ethical web scrapers != dangerous.

Just a dick move.


Sometimes it’s illegal. I’m sure I’m not the only developer here who has had to write accessible code to fulfill a project’s legal requirement.


You're correct, and I work for an organization that explicitly promises accessible websites. Gov't sites also require accessibility.


what if your website offers medical advice? Some people have to maintain things like WebMD.


WebMD is not a reliable source of medical information.


These patterns look familiar to me, having retrofitted a functional, though poorly architected AngularJS app for WCAG compliance. Would it have looked better if from the beginning semantic HTML were used? Sure. But does the aria- and role- soup improve the functionality and usability for non-typical users with little impact on maintainability? You bet.


> A click event on a div triggers only on click. A click event on a button triggers on click and if the users presses the Enter or Space key.

that is not 100% correct. a formular with a submit button will actually trigger on enter. but not a button per se. especially not a <button type="button">.


Looks like someone changed design decision and needed buttons instead of text links in various places and people got bad day implementing those.


good practices and HTML don't really exist, the reason we have things like buttons inside a div and other hacks like that are because the web evolved too fast and people had to find solutions to bugs / problems.


That's not true, is it? You're supposed to use the right tags so people with visual impairments can use screen readers to gather the right info, and so people can gather the data of your source more effectively. If you do this from first principles it's actually quite simple and integrates better with the css / js. Overuse of tags if anything just makes it more complicated.

The html may as well be the bedrock of your entire website, why not put in the extra work to find the best solutions?


>it's actually quite simple and integrates better with the css / js

That is just untrue, it that was the case, people wouldn't go for hacks, I agree the web for some parts are in a better state now that a few years ago, but for me it is still a nightmare, between features / tags / attributes that only works with X or Y browser, the number of bugs, the number of features still not released after being requested for years. Also if you want a specific design for your websites, sometimes going for <div> instead of "that more correct element that adds loads of shitty css by default" prevents some headache and allows you to prototype faster.


> good practices and HTML don't really exist

They do, we have a standard for that, https://html.spec.whatwg.org/


#8 can actually be a very wise way to fallback without <noscript>


The given example no, the answer shown as a solution by the blog author, yes.


> #7 [...] table layout

> yeah, it's on a live production site still running

like HN. :)


I like how this site is just bash.org but for HTML snippets


Don't forget the overflow:hidden for paywalls/alerts: https://www.youtube.com/watch?v=9IYZ8mktk7k




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: