[HN Gopher] Do you know that there is an HTML tables API?
___________________________________________________________________
Do you know that there is an HTML tables API?
Author : begoon
Score : 233 points
Date : 2025-11-01 12:58 UTC (10 hours ago)
(HTM) web link (christianheilmann.com)
(TXT) w3m dump (christianheilmann.com)
| dtagames wrote:
| Tables died (thankfully) to make room for flex and grid. I can't
| see any use case for them at all anymore.
| begoon wrote:
| I personally disagree. When data is semantically a table, not
| just a "table-looking" layout, I would rather use the table
| tag.
| the__alchemist wrote:
| I think this is the gist of it. Tables were abused as general
| spaced 1D, and 2D styling components. Introducing proper
| general spacial styling components means we don't need to
| extend tables beyond their original purpose, but doesn't mean
| we shouldn't use them for that purpose!
| zetanor wrote:
| The use case for a table is to present data.
| SahAssar wrote:
| Tabular data? Tables have a purpose, it's just that people
| misused them for layout purposes.
| loloquwowndueo wrote:
| To be fair, we did that when there wasn't much choice for
| laying out web pages other than using tables. I was there!
| cogman10 wrote:
| Especially in ways that worked cross browser.
|
| Young folk don't understand just how wildly different IE5
| was to the Netscape or the Mozilla browser. Or just how bad
| Javascript was when it started to be used on the internet.
|
| I've lived through and seen the evolution. For all the shit
| the JS community takes for constantly revving frameworks,
| it's 1000x easier to make a website that looks the same
| regardless of browser due to a lot of these frameworks and
| browsers themselves evolving.
| dvratil wrote:
| It's not that long ago that tables were the only reliable
| layout tool for HTML emails (mostly due to Outlook
| supporting only very limited subset of CSS).
| embedding-shape wrote:
| How about displaying data in rows and columns in a accessible
| and easily styled way, without having to rely on JS and your
| own CSS to replicate a table? How exactly would you do that
| with HTML and CSS without using tables? Using flex and grid for
| those purposes don't make much sense unless you care about
| design above all else.
|
| <table> just gives you so many good defaults (semantic
| structure, accessibility, column styling, column alignment,
| keyboard navigation) for free compared to using CSS to create
| your own table, that I'm not sure why you wouldn't use <table>
| for tabular data.
|
| Of course, if you need masonry, card grids and so on it makes
| sense, do actual layouting with layouting tools. But thankfully
| <table> hasn't died just yet, it's still better than CSS for
| many use cases.
| dtagames wrote:
| Nothing about flex or grids requires JS. That's entirely CSS.
| andai wrote:
| This implies that you were considering -- for a split second --
| making a 90s style table based website layout, using the Tables
| API? ;) I might have to try that now...
| pikuseru wrote:
| They're probably still quite useful for displaying tabular data
| - there's also semantics involved, it's not primarily just a
| layout mechanism.
| theandrewbailey wrote:
| How about displaying data in rows and columns, like records in
| a database? Or have you forgotten SQL, because you retrieve
| JSON from your 1000 NoSQL microservices?
| dtagames wrote:
| Rows and columns are exactly what grid was added to CSS for.
| theandrewbailey wrote:
| Using only CSS for tabular row and column data is just as
| wrong as using tables for layout. There are legit reasons
| for using <table> today that can't be replicated by CSS.
| Namely, CSS doesn't confer the same semantic meaning into
| markup that <table> does.
|
| Compare https://developer.mozilla.org/en-
| US/docs/Web/HTML/Reference/...
|
| with https://developer.mozilla.org/en-
| US/docs/Web/CSS/CSS_grid_la...
| nophunphil wrote:
| I agree with many other replies here, specifically about
| accessibility. Once I learned how to use a screen reader, it
| was eye-opening. So many web applications are utterly broken
| for users with assistive technologies.
|
| Tables built with flex and grid absolutely can be made
| accessible with WAI-ARIA, but native table elements are harder
| to mess up.
| thatwasunusual wrote:
| > That way they'd finally get the status as data structures and
| not a hack to layout content on the web.
|
| I remember doing this 25 years ago, but I assume (and hope) it's
| a huge minority who do this today?
| embedding-shape wrote:
| _cough_ view-
| source:https://news.ycombinator.com/item?id=45781293 _cough_
| bstsb wrote:
| intermittent loading errors (503 Service Unavailable)
|
| https://archive.ph/APbi8
| zX41ZdbW wrote:
| I was using it just half a year ago, after either reading MDN or
| reading what AI suggested. Which means, this API is not obscure
| and not forgotten. Using `rows` and `cells` is very convenient
| for keyboard navigation across table cells.
|
| https://github.com/ClickHouse/ClickHouse/blob/master/program...
| conception wrote:
| The worst thing on the modern web is people using divs for
| table data. What do you mean this table isn't sortable? M365
| Admin is the worst offender I've come across on this. Just
| terrible table implementations on almost every page.
| mr_toad wrote:
| Is there a term for the opposite of cargo culting? Where
| everyone avoids something, but no one remembers why? Because
| that's basically where HTML tables have ended up.
| embedding-shape wrote:
| I think this is something like a "delayed cargo culting",
| or "cargo culting based on outdated facts". I think it's
| basically the same as the hypothesis from the "Monkey
| Ladder Experiment", where monkeys got punished when trying
| to get a banana, and eventually all the monkeys were
| replaced with monkeys that didn't realize _why_ the banana
| was off-limits, yet persisted in trying to "help" other
| monkeys trying to prevent them from getting the banana.
|
| I'm not sure if I read that that specific experiment was
| debunked or not, but it certainly sounds familiar to how
| some developer trends get propagated even though the ground
| truth as changed.
| paradox460 wrote:
| It's still cargo culting
| joquarky wrote:
| I would guess that people became so afraid of being accused
| of using tables for layout that they don't use them at all.
| ralusek wrote:
| Using HTML Tables doesn't just make your data sortable
| skerit wrote:
| Interesting, but the JavaScript examples hurt:
| let table = [ ['one','two','three'],
| ['four','five','six'] ]; let b = document.body;
| let t = document.createElement('table');
| b.appendChild(t); table.forEach((row,ri) => {
| let r = t.insertRow(ri); row.forEach((l,i) => {
| let c = r.insertCell(i); c.innerText = l;
| }) });
|
| Use full words for variable names!
| niek_pas wrote:
| I was just about to comment the same. I'm sure people have a
| good reason for it (or at leafy _a_ reason), but single-letter
| variable names always struck me as optimizing for the wrong
| thing.
|
| As someone who likes to program in Haskell, I feel this pain
| very strongly. :)
| bottd wrote:
| Do you always feel this is the case? To me the go to single
| letter variables are very readable. Used so widely my eyes
| parse them like other symbols: =, &, +, etc.
| alentred wrote:
| My rule of thumb: only using single letter variables in
| one-liners (and never if it spills to another line), or for
| something that is conventionally represented as such. So
| for example: ```python bar =
| [foo(e) for e in elements] ```
|
| or, using `x`, `n`, `s` and similar when they represent
| just that, a generic variable with a number, string, etc. I
| think there is a Code Complete chapter about it.
| jazzypants wrote:
| Yeah, I'm not GP, but my exceptions to this rule are `i`
| for "iterator" in `for` loops and `e` for "event" in
| event listeners.
| NetMageSCW wrote:
| Don't use 'i' (looks like 1), use 'j1', etc - helps set
| you up if you need a nested loop someday. Of course, at
| that point better naming would probably be best.
| adamddev1 wrote:
| Strong BASIC memories. On the Apple IIe, anything after the
| first two characters of variable names was ignored.
| croes wrote:
| In real ok, but in this short example it's pretty obvious
| what t,b, r and c mean
| ninjin wrote:
| Really? The variable name lengths? Not that the code is clearer
| as: const te =
| document.createElement('table');
| document.body.appendChild(te); [ ['one',
| 'two', 'three'], ['four', 'five', 'six' ],
| ].forEach((r, i) => { const re = te.insertRow(i);
| r.forEach((c, j) => {
| re.insertCell(j).innerText = c; }) });
|
| My personal stance on short variable names is that they are
| fine as long as their scope is very limited, which is the case
| here. Rather, the "crime" to me is an overuse of rather
| pointless variables as the majority of them were only used
| once.
|
| Disclaimer: I have not tested the code and I only write
| JavaScript once every few years and when I do I am unhappy
| about it.
| matt_kantor wrote:
| Looks like your code inserts a new row for every cell.
| ninjin wrote:
| Cheers! Fixed.
| jonathrg wrote:
| This is not an improvement. Having named variables for things
| is good actually. They will need to be declared again
| immediately once you want to modify the code.
| insertCell(i).innerText = c is a nonsense statement, it
| should be 2 lines for the 2 operations
| AlienRobot wrote:
| Personally I'd make everything const instead of let and use for
| of instead of forEach, but it's like 10 lines of code it
| doesn't really matter.
| Sharlin wrote:
| Are you sure this old API does the right thing with for...of?
| kaoD wrote:
| It's only used to iterate the array
| Sharlin wrote:
| Oops, right, I confused the variables.
| runarberg wrote:
| Should work just fine: >
| document.createElement("table").rows[Symbol.iterator]()
| // Array Iterator { constructor: Iterator() }
|
| HTMLTableElement.prototype.rows actually just returns a
| HTMLCollection, so same as document.forms, or
| document.getElementsByClassName. HTMLCollection implements
| Symbol.iterator as you would expect.
|
| https://developer.mozilla.org/en-
| US/docs/Web/API/HTMLTableEl...
| layer8 wrote:
| A bike-shedding thread on top as usual.
| poisonborz wrote:
| Code quality is not bike shedding.
| Sharlin wrote:
| It is, however, off topic and beside the point. And whether
| short names are a code quality issue is a rather contested
| and context-dependent topic.
| nkrisc wrote:
| Code quality of... an example snippet?
| davidmurdoch wrote:
| Especially
| blackcatsec wrote:
| especially now that the example is gonna end up in some
| LLM somewhere and folks will just copy pasta.
| refulgentis wrote:
| Usually I'd cosign, but I get it, after a similiar issue I
| had a couple days ago with a Rust article that was _insanely_
| frustrating to deal with.
|
| It's a brain scramble because you can't just read in toto.
|
| Well, you can _literally_ , but, you don't feel like you grok
| it.
|
| And when you take a second pass you gotta slow down and stop
| and parse "what's r here? is it relevant? oh rows?"
|
| It's one of those things that's hard to describe because _it
| doesn 't sound like much if you got it_. And this example is
| trivial, especially if you're not open to the idea its a
| problem (r/c = rows/columns) But it's nigh-impenetrable in
| other scenarios.
|
| You feel like you're barely understanding something that you
| actually might grok completely.
| embedding-shape wrote:
| > It's one of those things that's hard to describe because
| it doesn't sound like much if you got it. And this example
| is trivial, especially if you're not open to the idea its a
| problem (r/c = rows/columns) But it's nigh-impenetrable in
| other scenarios.
|
| I agree, it's highly context-specific.
|
| In a small demo for a small blog post with basically no
| complexity? Go ahead, use 1 character variable names, it
| really isn't difficult.
|
| In the 1000 long CUDA kernel where you barely understand
| what's going on even though you understand the concepts?
| I'd be favoring longer descriptive names than one letter
| names for sure.
| bfkwlfkjf wrote:
| Yeah I see this a lot on HN. I think people feel the need to
| make precise and accurate statements about things. I think a
| lot of them, if they'd deep breath and waited 30 minutes,
| they wouldn't comment.
| embedding-shape wrote:
| The internet is filled with pedantics, creeps and dogs
| posing as cats. The whole "take a breath" thing was early
| abandoned in favor of the now traditional "reply until the
| other party gives up" approach, which requires you to
| really dig into their messages and point out spelling
| mistakes, fallacies, and for programmers, variable names.
| skerit wrote:
| It's hard to read, especially in the lambdas.
|
| It's a small critique, I'm sorry it got upvoted by other
| people.
| dang wrote:
| I understand the frustration (probably no one feels it more
| than we do, because it's our job to help discussion stay
| meaningful). But please don't respond by posting like this.
|
| It takes time for the contrarian dynamic to work itself out (
| https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que.
| ..), and once that happens, the original problem subsides but
| and the secondary problem (shallow objection to the
| objection) sticks out like a sore thumb.
|
| It's usually enough to downvote (or, in egregious cases) flag
| a post that shouldn't be at the top. In really egregious
| cases, emailing hn@ycombinator.com is also a fine idea.
|
| From the guidelines: " _Please don 't sneer, including at the
| rest of the community._" -
| https://news.ycombinator.com/newsguidelines.html
| phoronixrly wrote:
| Looks to me like it's following the JS conventions... Jk, no
| such thing exists still!!
| Sharlin wrote:
| It's normal to use short names for things with short scopes.
| foofoo12 wrote:
| Yes, and the reason for why that's OK is that the context is
| just few lines. But this is borderline due to the amount of
| variables.
|
| In just 4 lines you have r, row, t, ri, l, i and c.
|
| The full variables names are so short anyway that personally
| I'd write them out. Code does evolve and there's a risk of
| this suffering as a result.
| Sharlin wrote:
| That's a fair point.
| NetMageSCW wrote:
| rowIndex isn't that short.
| bdangubic wrote:
| shortness is in the eye of the beholder... program with
| spring framework long enough and rowIndex sounds like
| abbreviation. :)
| foofoo12 wrote:
| RowIndexFactoryGeneratorService
| rowIndexFactoryGeneratorService = new
| RowIndexFactoryGeneratorService(); RowIndexFactory
| rowIndexFactory = rowIndexFactoryGeneratorService.getTheF
| actoryOrSomethingIDontCare(); RowIndex rowIndex =
| rowIndexFactoryGeneratorService.generateRowIndex();
| foofoo12 wrote:
| We might be able to use rowIx? Let's discuss it on the
| next Monday standup. Everyone will need to have an
| opinion, max 5 minutes per person.
| shiandow wrote:
| I think the short names aren't anywhere near as bad for
| readability as using (ri,i) as a table index.
|
| If you're going to use short names at least make it clear which
| belong together. Especially don't use different lengths when
| things ought to be similar.
| data.forEach((row,i) => row.forEach((ele,j) => ... ))
| jfengel wrote:
| It's the lets that bother me. The point is elderly JS, and the
| entire operation is fundamentally imperative. But this code is
| brimming with opportunities to make mistakes. JS deserved its
| reputation.
| fsckboy wrote:
| > _Use full words for variable names!_
|
| that's like saying in spoken language "don't ever use pronouns,
| or even first or nicknames, use full given names"
| groguzt wrote:
| you are being intentionally dense, they are saying "don't use
| a single initial to identify someone, use their firstname
| instead"
| egorfine wrote:
| > let b = document.body;
|
| This one hurts the most. Save a few bytes for an ungodly amount
| of mental friction.
| tbrownaw wrote:
| It doesn't save any bytes, that variable is used _once_.
| Mystery-Machine wrote:
| The variable naming convention used here could be improved for
| clarity. I prefer appending `El` to variables that hold DOM
| elements, as it makes identifiers like `tableEl` clearer and
| helps avoid ambiguity between variables such as `table` and
| `row`. Also, the variable named `table` does _not_ actually
| represent a table element; it would be more accurate to name it
| `data` or `tableData` to better reflect its purpose.
| embedding-shape wrote:
| Probably because I first learned programming with JavaScript
| and very early started using jQuery, but I've always used
| prefixed `$` to indicate "This is a DOM element" (started doing
| this once jQuery stopped being so popular). So the example
| would be something like this for me: let table
| = [ ['one','two','three'],
| ['four','five','six'] ]; let $body = document.body;
| let $table = document.createElement('table');
| $body.appendChild($table);
|
| Always felt it worked out short and sweet, and as long as
| you're not refactoring a jQuery codebase, seems to work out
| well in practice.
| pspeter3 wrote:
| I'm curious what changes the author would like to see to the API
| stared wrote:
| It is similar as with buttons
| (https://news.ycombinator.com/item?id=45774182).
|
| Not sure when it was (10-15 years ago), but at some point
| everything became <div>s. So, instead of semantic markup, HTML
| became a UI toolbox.
| macintux wrote:
| I think it was inevitable. Most of the funded content on the
| web is marketing/sales-driven, and companies paying for
| marketing content want it to be displayed in a specific way.
|
| It'd be interesting to have a parallel DocBook web for
| technical content, where consumers of that content could apply
| their own styles to render it in a way that's best for them.
| jazzypants wrote:
| I mean, you can just remove all the user agent styles and
| then <button> is just as stylable as <div>.
| macintux wrote:
| Why would marketing want to pay for the extra (and to their
| mind entirely pointless) work required to capture
| semantics?
|
| (I'm not saying I like the world we live in, but I don't
| see a likely alternative.)
| withinboredom wrote:
| Because not everyone has useful eyeballs. Some people are
| blind. The amount of extra work you have to do to make a
| div faithfully act like a button is far more than simply
| resetting some styles.
| macintux wrote:
| It seems evident to me that semantics are more
| challenging to define than visuals; it's not the CSS
| that's the problem.
| lwhi wrote:
| It's more challenging to encourage correct implementation
| of semantics than implemention of visuals; which is a
| great reason for using the element that was designed for
| this use case.
| mpeg wrote:
| I've literally never had a marketing person tell me
| whether I should use a <button> or <div>. Let's not
| pretend things like using the wrong semantic elements is
| anyone else's fault but lazy or inexperienced developers.
|
| These days it's a moot point anyway, because everyone is
| using things like tailwind which provide a full reset for
| things like default buttons, so there really is no
| excuse.
| nonethewiser wrote:
| That's because the DOM is mostly used as a render target
| instead of a semantic document.
|
| I think semantic HTML is a great idea but it's kind of jaded to
| expect it at this point.
|
| It also doesn't help that semantic elements have styling. That
| right there gives people good reason to use a neutral container
| as a baseline. In fact I would go as far as to say that having
| both div and span is a bad design decision. They are just
| aliases for css `display` values.
| joquarky wrote:
| The semantic web never took off because companies don't want
| to make their content easy to scrape.
|
| Just look at how they salivate for WASM where everything is
| closed up and inaccessible, including a11y.
| art0rz wrote:
| I've been writing HTML for at least 20 years professionally and
| this has absolutely not been my experience. Yes, I've
| encountered some people using divs for everything but in the
| vast majority of cases people have used semantically correct
| HTML, at least when it comes to buttons.
| Insanity wrote:
| Phew, this post single handedly made me feel old this morning. I
| started dabbling with the web just over 20 years ago but have
| mainly been working on the backend the past 10-15 years. I had no
| clue that nowadays programmers don't know about this, so I assume
| it's supplanted by modern frameworks or modern JS/CSS
| dmd wrote:
| Same. I use this all the time, have for decades. Had no idea
| other people didn't.
| zkmon wrote:
| Just a catchy title. Not abandoned etc. This is the only API
| available to manipulate HTML table tags.
| jazzypants wrote:
| Most people use declarative frameworks to build tables, and
| you could just use `innerHTML` or `append` or any other
| imperative DOM API to work with tables.
| moritzwarhier wrote:
| Declarative frameworks build on the imperative DOM API.
| jazzypants wrote:
| And, not a single one of the declarative frameworks use
| the HTMLTableElement API!
| zkmon wrote:
| So how they do they talk to the browser to add a row to
| the table? Do you know of any API other than DOM used for
| this?
| plorkyeran wrote:
| They use createElement instead of the table-specific API.
| simonw wrote:
| They don't use .insertRow() and .insertCell(). Try
| searching the React codebase for those.
| zkmon wrote:
| What do they use?
| simonw wrote:
| appendChild() and the like.
| moritzwarhier wrote:
| Yea, but that's pretty much irrelevant as long as the
| effect is exactly the same. Which brings us back to the
| point of the article: seeing this and feeling inspired to
| imagine interface extensions that go beyond syntax sugar.
|
| I was replying to the wrong comment, because I was
| responding to this:
|
| > I still use this pretty much everywhere to create HTML
| tables. Do people use something else now?
|
| Regarding React: what would be the benefit for using this
| old syntax sugar in its vDOM implementation?
|
| Page reflow is not an issue for vDOM as it batches such
| updates anyway?
|
| And using syntax sugar without benefits in the DOM
| reconciliation would be pointless.
|
| React also doesn't locate form input elements using
| document.forms.[name]?.[name] because... why should they?
|
| Just because they can...
|
| Regarding the creation of tables, the most common way to
| do it would be... parsing initial document's HTML?!
| moritzwarhier wrote:
| appendChild, replaceChildren, etc work fine with tables?
| alentred wrote:
| Thank you for confirming I am not... crazy, just old then. I
| was staring at the code for minutes, trying to spot something
| unusual that I missed. So, this really just about the `<table>`
| element, or do I actually not see something?
| paperpunk wrote:
| It's not about the table element, it's about the API to
| construct and manipulate that element with a columns and rows
| interface which is largely superseded by general DOM
| manipulation.
| littlestymaar wrote:
| Exactly like how `getElementById` replaced the direct use
| of the id as a JavaScript identifier.
| xg15 wrote:
| I remember there being posts that explicitly discouraged
| using IDs directly, but I'm not sure of tge reasons
| anymore. Maybe browser incompatibilities or unclear
| scoping and confusion with other variables?
| withinboredom wrote:
| It was either Mozilla (Netscape, I think) or IE that it
| didn't work on for the longest time.
| mook wrote:
| I think that was a native IE API that Mozilla had to add
| support for, as well as document.all (Netscape used
| document.layers).
| chrismorgan wrote:
| It works everywhere (it's now specified in
| https://html.spec.whatwg.org/multipage/nav-history-
| apis.html...), but it's brittle. It can break by adding
| colliding properties to window deliberately or by
| accidental global leak (... including things like setting
| in dev tools), by browser defining new globals, by some
| 'name' attribute conflict.
| xg15 wrote:
| It's about the insertRow() and insertCell() methods and
| rows[] and cells[] fields on the table element, not the table
| itself.
| eterm wrote:
| I figured that was the normal way to interact with tables,
| what would people do otherwise?
| xg15 wrote:
| Using the standard DOM APIs or - if they don't care about
| anything - innerHTML, I suppose.
| kleiba wrote:
| Sorry I - also - am one of those old timers who don't
| understand this because the shown code is all I've ever
| used for creating table. So, what is this "standard DOM
| API" if I may ask? Could you post a code example?
| wging wrote:
| You can use document.createElement and
| document.appendChild to create every last <th>, <tr>, and
| <td> if you want. Those functions are not specific to
| tables, unlike the one mentioned in the blog post. They
| can be used to create any elements and place them in the
| DOM. But if you know what you are doing you can get a
| perfectly fine table out of that. (Not that you should.)
| xg15 wrote:
| Yeah, that was what I was thinking of. I knew those as
| the essential APIs to modify the DOM without a full re-
| parse. And you can use them on table/th/tr/td nodes just
| like on any other node.
| thorum wrote:
| createElement('tr') and table.appendChild(row)
| jcpst wrote:
| Yep, didn't realize this was unknown by enough web developers
| to warrant an article.
| embedding-shape wrote:
| I see new frontend developers using <div> for building
| buttons, and I've even seen people using <div> for doing
| titles! Us greybeards don't know how much apparent knowledge
| we're sitting on, it seems.
| jfengel wrote:
| Is that bad?
|
| Seems to me that we have redundant mechanisms for
| specifying semantics: tags and attributes (and classes as a
| specific attribute). Seems to me that tags are really just
| syntactic sugar for things like roles. Tables in particular
| are easily abused.
|
| Of course I use the tag names, because they're idiomatic.
| But I feel like a newbie who identifies divs as the only
| true structure builder has a proper developer's intuition
| for separating presentation from content.
| embedding-shape wrote:
| > Is that bad?
|
| As long as you think about semantics and accessibility
| and does the extra work to add those things, then not
| really.
|
| But why add those extra things when we already get those
| for free by doing <h1> and then customizing the style?
| Everything you'd need to manually add, automatically
| works fine then, so seems like a no-brainer to avoid
| putting more work on your table.
| swiftcoder wrote:
| div-as-button/link leaves a lot of default interaction
| behaviour on the table. You'll need to handle all the
| keyboard interactions yourself, all the accessibility
| markup, etc.
| withinboredom wrote:
| And spans for creating links...
| LaundroMat wrote:
| Thereby forgetting that some people like to open links in
| a new tab.
| embedding-shape wrote:
| And for the ones that remember to implement middle-mouse
| click to open new tabs, forgets that one can also do
| CTRL+click to open in new tab, or vice-versa.
|
| Just use <a> please :)
| Izkata wrote:
| I recently discovered our frontend widget library draws
| an SVG to implement Radio instead of using <input
| type="radio">. I was looking at it because they forgot to
| add a "disabled" attribute.
|
| Best case I'm hoping it's because they were required to
| get an exact design, but they really should have pushed
| back on that one if so.
| jacobyoder wrote:
| In _2004_ I was at a company that dedicated a team of
| people to rebuilding a bunch of tables (lots of financial
| data) in to styled divs because... "tables are
| depreciated". The fact that they couldn't pronounce or
| understand the word "deprecated" should have been enough of
| a clue to ignore this person, but they were the 'lead' on
| the web team, and... had been there longer than other
| people. Obviously they must know what they're talking
| about. Weeks later after having converted dozens of
| spreadsheets to divs (instead of just using tables) they
| were 'done', but it was a tremendous waste of time that
| ignored all the semantics of tables. I was asked to 'help
| out' on that project to meet the deadline and refused,
| citing that it was not just stupid, but a big waste of time
| and against web semantics.
|
| "table" was never deprecated in HTML at all, but was
| discouraged for general layout (we were aware of this even
| in the early 2000s). But for representing tabular data -
| like... data in rows/columns from spreadsheets (with column
| headers and such)... HTML tables were absolutely the right
| (only?) way to present this.
|
| I was at that company less than a year...
| bryanrasmussen wrote:
| I knew it existed but I figured it was only really useful for
| extremely data-table centric applications so I've never used
| it.
| prokopton wrote:
| I've been doing ssr for so long I can't fathom why you'd build
| a table using JS.
| EvanAnderson wrote:
| I've been working on a little SPA that manipulates tabular
| data and allows the user to insert rows. This is exactly the
| API I've been using. Like a lot of other commenters it never
| occurred to me that people wouldn't know this API exists.
|
| Aside: I started with Perl CGI scripts, then ColdFusion, and
| finally Classic ASP back in the 90s. I had a chuckle a couple
| years ago dealing with a younger developer who was shocked
| that and oldster like me was up on new-fangled SSR patterns.
| spinningarrow wrote:
| I've been building sites since around 2000 and I've used HTML
| tables a lot (including for page layouts, remember those
| days?). There was a time when I thought I was fluent enough to
| not have to look up HTML or CSS docs for most things. But I
| don't think I've ever actively used the DOM API that this
| article mentions so I learned something new today.
| mattmanser wrote:
| Surprised, as we used this a lot around 2005, when IE6 was
| still dominant.
|
| If was much simpler to build tables in javascript with this
| rather than using document.createElement.
|
| Perhaps this was one of those things that you just had to
| know about, or be working on data heavy web apps.
| simonw wrote:
| You knew about the .insertRow() and .insertCell() methods?
| spiderfarmer wrote:
| I made my first CRUD UI that didn't do full page refreshes
| with those methods.
| embedding-shape wrote:
| I think most of us did the ol
| `$el.appendChild(document.createElement('tr'))` dance
| rather than using those, at least I did during the 00s for
| sure.
| phkahler wrote:
| HTML tables are cognitively if not officially deprecated these
| days. I made my 1996 resume in HTML using a table for layout
| and it was indistinguishable from the Word version when
| printed. Made by editing the HTML by hand too!
|
| Tables are great. I don't doubt that CSS stuff is more capable,
| but the old ones are still useful.
| xg15 wrote:
| I think the problem was that tables were always supposed to
| be for things that look like actual tables in the output -
| for that purpose they are not deprecated.
|
| What is discouraged is using tables as invisible layout grids
| - and that was their primary de-facto usecase before CSS and
| grid layouts. But that had always been a hack, even though a
| necessary one.
| fortyseven wrote:
| Yep. Tables for tabular data are still on the menu.
| leptons wrote:
| Tables are probably still useful for layout in HTML emails
| (for advertising). I haven't had to work with HTML emails
| in probably 20 years, but I doubt much has changed about
| what is and isn't allowed in HTML emails.
| euroderf wrote:
| > What is discouraged is using tables as invisible layout
| grids - and that was their primary de-facto usecase before
| CSS and grid layouts.
|
| After too.
|
| I've seen enough "Introduction to CSS"s filled with caveats
| and hemming & hawing to know that it's all to be avoided
| when+if possible. I know, I know, there's a whole wide
| wonderful world out there full of aligns and borders and
| containers and insets and margins and masks and offsets and
| paddings and positions oh my. Bleccch..
| cruffle_duffle wrote:
| Back in the early to mid 2000's, making your site "table
| free" while still working on IE6 was seen as a badge of
| masochistic pride.
|
| Doing table-free multi-column layouts involved doing crazy
| "float: left/right + padding + margin" with an heavy sprinkle
| of IE6 clearfix hacks to work right. I mean eventually people
| dialed in the correct incantations to make table-free designs
| work for IE6 but it was never quite as straightforward or
| reliable as a good old fashioned table. Many megajoules of
| energy were wasted on webform drama between the pragmatic
| "fuck you, tables just work and I have shit to ship" webdev
| and the more academic "tables break the semantic web and
| aren't needed, use CSS." crew.
|
| Like most things, the "tables are evil" mantra was taken too
| far and people started to use floated divs (or <li/>'s or
| <span/>'s or whatever) for shit that actually _was_ tablular
| data! (I was guilty of this!).
|
| And like most things, a lot of the drama went away when IE6
| finally went away. People who weren't around back then simply
| cannot understand exactly how much IE6 held back modern web
| design. You could almost count on half your time being spent
| making shit work for IE6, despite the ever decreasing amount
| of traffic it got. I'm pretty sure I almost cried the day
| Google slapped a "IE6 will no longer be supported" on it's
| site.... the second they did that, my site got the exact same
| banner. Fuck IE6. The amount of costs that absolute pile of
| shit browser caused the industry exceeded the GDP of entire
| nations.
|
| Anyway.... back to adding weird activex shit in my CSS so IE6
| can support alpha-blended PNGs....
| icedchai wrote:
| I remember those days. It was simpler to use tables for
| layout than to use early CSS for quite a while.
| ranger_danger wrote:
| > HTML tables are cognitively if not officially deprecated
| these days.
|
| According to who?
| nunez wrote:
| I feel like I used this when I built a red-light, green-light
| dashboard for Windows servers at a bank for my first job out of
| college (in 2009).
| JofArnold wrote:
| It's worth checking who the author is... Cristian's not exactly
| new to the game. I think he's being humble he doesn't know
| something despite his experience.
| zkmon wrote:
| Abandoned? When? I still use this pretty much everywhere to
| create HTML tables. Do people use something else now?
| jckahn wrote:
| Yes, React
| iammrpayments wrote:
| Why would anyone use this outdated code over useInsertRow()
| and useTableColumnEffect()?
| NetMageSCW wrote:
| What are those and where are they in standard Javascript /
| DOM API?
| zkmon wrote:
| And what does that use internally to manage tables? Just
| because there is layer between you and the API, it doesn't
| mean API is abandoned.
| __jonas wrote:
| Are you implying that when doing DOM reconciliation, React
| uses these table-specific insertRow/insertCell APIs for
| adding and removing elements in tables instead of the
| regular DOM element APIs it would use for all other
| elements? I would be surprised if that's the case.
| mpeg wrote:
| The funny thing is the insertRow/insertCell API just call
| into DOM manipulation functions like appendChild
| internally, they just provide some syntactic sugar around
| things like managing the rows/cells array. It's all the
| same
|
| https://github.com/WebKit/WebKit/blob/28fa568972a4d34d867
| 948...
| embedding-shape wrote:
| Why would it matter what library you use? I'm using React, I
| do <table> whenever I need to display tabular data, React or
| no React as no impact on when I'd use <table>.
| iammrpayments wrote:
| Just make sure to pass a subscriber to useSyncExternalStore
| if you decide to venture outside React and use
| HTMLTable.insertRow, you see react is really smart and
| won't let you use this piece of outdated code without
| punishing you with side effects.
|
| Thanks Vercel & Meta for protecting us.
| embedding-shape wrote:
| > Just make sure to pass a subscriber to
| useSyncExternalStore if you decide to venture outside
| React and use HTMLTable.insertRow, you see react is
| really smart and won't let you use this piece of outdated
| code without punishing you with side effects.
|
| Huh? Why'd you involve state in this or any imperative
| code? You render the rows/columns as you'd render any
| other DOM elements in React, pass in the data as props
| and iterate on it, create children and pass them to
| render.
| withinboredom wrote:
| InsertRow updates the live DOM and React just wholesale
| replaces it. It's a masterstroke footgun.
| embedding-shape wrote:
| Yes, your point? Anyone who spend 15 minutes learning
| about React learns that you don't manipulate the DOM
| directly, you let the rendering engine handle that for
| you.
| iammrpayments wrote:
| Yes that's why of instead of learning the standard apis,
| you have to spend 15 months learning how to debug
| useEffect
| embedding-shape wrote:
| Or just skip all of the newly released stuff and use
| React as it was originally made, like me and many others
| still do. Never suffer from having to debug "useEffect"
| because we literally never use it. You don't _have to_
| use the newest and shiniest toys, especially not those
| with footguns.
| moritzwarhier wrote:
| React is as orthogonal to DOM manipulation API as it is to
| letting the browser render tables from HTML.
| moritzwarhier wrote:
| Abandonware is a clickbait title insofar as it normally refers
| to licenses, not standards.
|
| The idea of the author seems to be that this part of the DOM
| API that could benefit from backwards-compatible additions. So,
| by "abandoned", he hints at the headroom for building more
| table capabilities into the platform.
|
| He compares it loosely to the form element API and the
| additions it received over the last decades.
|
| In the case of tables, I could think of things such as a
| sorting, filtering API, but I can't tell whether that's what he
| means.
| __jonas wrote:
| People often use declarative UI frameworks such as React,
| Svelte etc. when they want to build things dynamically in JS
| like that now, so imperative DOM manipulation APIs have
| unsurprisingly become a little more niche.
| littlestymaar wrote:
| If by "Niche" you mean "not hype" then yes, but the
| PHP+jQuery combo is still very widely used in 2025 (likely
| more than React, given WordPress market share alone).
| __jonas wrote:
| Sure! But if you render server side (as with PHP), you'd
| likely just build up your table on the server rather than
| dynamically on the client, so you would also not use these
| imperative table element specific APIs.
|
| Even if, for some reason, you were filling in the table
| content dynamically via jQuery, I think the fashion there
| was also to just pass in whole HTML markup snippets as
| strings to be injected into the DOM, so you'd also more
| likely use plain <tr> elements than this table-specific
| API, same as with a 'hype' framework of now.
| smusamashah wrote:
| I used this for a small tool I was making to see stable Diffusion
| images in a table to compare images on different set of
| parameters, had lots of rows and columns. I needed to regenerate
| tables quickly, I vaguely remember this API being much slower
| than making rows/cells via strings. The reason I found was that
| each call using this API updates DOM and with string it's all in
| one go (or something similar).
| est wrote:
| please rediscover html form API
| xg15 wrote:
| > _Without having to re-render the whole table on each change._
|
| That's nice, but isn't that what the standard DOM methods are
| already doing? Or does that API have any additional abilities?
|
| Nevertheless, that's really cool and potentially saves a lot of
| tedious and error-prone DOM navigation.
| righthand wrote:
| Will Google remove this API then if it's abandoned?
|
| Topic is reminiscent of a submission from yesterday about XSLT:
|
| https://news.ycombinator.com/item?id=45779261
| simonw wrote:
| XSLT requires hundreds of thousands (maybe millions?) of lines
| of security-sensitive code. That's why it's proposed for
| removal.
|
| I doubt that's true for .insertCell() and .insertRow().
| runarberg wrote:
| I feel like IndexedDB is becoming this abandonware as well. There
| are so many ways where this (IMO rather badly designed) API can
| be improved but the standards committee seems completely
| uninterested. Even things like adding BigInt as primative is
| unimplemented.
|
| I fear this will be even worse now that we have the origin File
| System API and people can bring their own database engines (like
| web-assambled SQLite). But for those of us that are striving
| towards smaller download sizes this is a disaster.
| psadri wrote:
| The trouble is not populating it. The trouble is that tables,
| even though structured semantically, give you absolutely no
| functionality. There are no search, filter, sort, or selection
| features that you get.
| qzzi wrote:
| Compared to what? What gives you all that, and what prevents
| you from having it with tables?
| kgwxd wrote:
| countless plugins for use in countless frameworks. We should
| have all that built-in by now. like we finally have a
| functioning date picker.
| mcintyre1994 wrote:
| Javascript arrays have functions for all of that, so if you
| use something like React and renders your table from data
| arrays then it's all pretty trivial. I guess the point is
| that if you have to use JS to do those manipulations, then at
| some point it's going to be easier to just the
| React(/Vue/Svelte/etc) approach than manipulating the table
| yourself using the API described in the article.
| joquarky wrote:
| Frameworks that make development easy are inherently
| inefficient. If performance is priority, then you better
| sort it yourself.
| StrauXX wrote:
| > Without having to re-render the whole table on each change.
|
| Not quite sure what the author means by that. Re-rendering pnly
| happens when the current task queue elemt has been processed.
| Never while JS is running (aside from webworker and the like). I
| would honestly be surprised if this API had much (if any)
| performance benefits over createElement.
| mpeg wrote:
| I quickly looked into the webkit code and there's probably
| absolutely no performance benefit, the same logic should be
| running behind the scenes
| _the_inflator wrote:
| Sure!
|
| And there is way more to it.
|
| This kind of code was common and also the starting point of every
| modern language innovation we have today in JavaScript - even
| TypeScript, and maybe any modern web development on the server as
| well.
|
| Tables were the only way to create browser independent layouts
| dynamically. Or put another way: adding interactivity to
| websites. And simply because hacking is fun and browsers were
| experimenting with APIs accessible by JavaScript.
|
| CSS was still bleeding from ACID tests, Netscape was forgotten,
| Mozilla build Phoenix out of the ashes of the bursting bubble and
| called their effort Firefox.
|
| In Germany there was and still is the infamous selfHTML project.
| I remember vividly reading and testing Stefans Munz tutorials on
| this topic. The content is untouched, only the layout changed, so
| go back in time for more table fun:
|
| https://wiki.selfhtml.org/wiki/Beispiel:JS-Anwendung-Tabelle...
|
| https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/Tabellen...
|
| It was pretty common to have large one file websites: php and
| html with css and javascript mixed.
|
| There was no git, no VisualStudio Code, Claude Sonnet - no,
| Notepad and later Notepad++
|
| (Even the DOOM guys had no version control system in the early
| stages.)
|
| For me John Resig shines out here. Epic genius behind jQuery. The
| source code was pure magic, and his book "Secrets of the
| JavaScript Ninja" is for me the all time climax in programming
| excellence.
|
| If you never utilised the prototype property, you will never
| understand any of the most basic structures and inner workings
| JavaScript has to this day and why Classes are "syntactical
| sugar" for functions and nothing else.
|
| Function.toString in combination with New Function made me enter
| 10 matrices in parallel at the time. What a revelation. :D
|
| Nicholas Zakas comes close with his seminal Web Development book,
| in which he featured every Browser API available at the time with
| examples on roughly 1000 pages. To this day, exercising most of
| it and understanding the DOM and Windows object was the best
| investment ever, because and this fact 15 years later paved the
| way for the success of a financial SaaS platform. Lost wisdom,
| not covered by any modern framework like Angular or ReacJS.
| tokioyoyo wrote:
| Woah, it's always weird to see how there's modern web engineers
| that didn't grow up during the era where entire layouts were
| built on tables. Not saying that it was good or bad, but just
| interesting.
| wombatpm wrote:
| I remember doing image maps, splitting large images up into
| pieces, placing them in table cells and adding links to each
| cell as a poor man's GUI
| The_President wrote:
| The depreciation of marquee and blink wasn't necessary; it's web
| developer's choice whether to use these and the visitor's choice
| whether to be repulsed. Marquee should have been improved for use
| as ticker elements for specialized application. The depreciation
| of nobr misses the point - the alternative is more complex. Hope
| the standard continues to keep the legacy elements: small, i, em,
| hr... etc.
| chrismorgan wrote:
| A _lot_ of people here are clearly not reading the article.
|
| It's not about the <table> element itself--we hope everyone knows
| about tables--but rather about the table-specific DOM interface,
| including things like HTMLTableElement.prototype.insertRow() and
| HTMLTableRowElement.prototype.insertCell() as alternatives to the
| generic DOM techniques like Document.prototype.createElement()
| and Node.prototype.appendChild().
|
| These are handy if you're hand-writing your DOM interactions, but
| libraries that construct and maintain DOM trees (e.g. React,
| Svelte, Vue) will never use them, and that's the direction
| everything has headed, so in practice they've fallen into near-
| complete disuse.
|
| They match HTML syntax in another important way: HTML tables have
| thead/tbody/tfoot section elements, but you can mostly skip
| writing them in HTML syntax because it'll imply <tbody> open and
| close tags. Likewise in this interface, if you have a
| thead/tbody/tfoot element you can call .insertRow() on it, but
| you can also call .insertRow() on the table, and it'll put it in
| the last tbody, creating one if necessary. Meanwhile, I presume
| in React/Svelte/Vue/whatever you must write out your tbody
| manually.
|
| I've definitely used at least .insertRow, .insertCell,
| .createTHead, .rows and .cells in the last five years in no-
| library throwaway/demo scripts where I was generating tables.
|
| --***--
|
| Concerning the specific example given, here's what I find a
| clearer code style, using for instead of forEach, using better
| variable names, and omitting the index argument to
| insertRow/insertCell which was _quite_ unnecessary and only
| confused matters (the author doesn't seem to have realised it's
| optional): let data = [
| ['one','two','three'], ['four','five','six'] ];
| let table = document.createElement('table'); for (const row
| of data) { let tr = table.insertRow(); for
| (const value of row) { tr.insertCell().innerText =
| value; } } document.body.append(table);
| joquarky wrote:
| I feel like frameworks have taken over and so few people know
| the foundations anymore. Thank you.
|
| I still remember reading a news article on C|net about the
| addition of the <table> element.
|
| Yeah, I'm old.
| BobbyTables2 wrote:
| The author didn't know the <TABLE> tag existed ???
| bane wrote:
| This is a great reminder that the Eternal September still exists
| and perhaps mercifully appears to be affecting those with at
| least some technical exposure.
|
| https://en.wikipedia.org/wiki/Eternal_September
| louissan wrote:
| Hey Chris :-)
___________________________________________________________________
(page generated 2025-11-01 23:01 UTC)