Build1 distinct publisher3 min readPublished
HTML5 constraint validation still blocks the submit event when a required field is empty, but if that field sits in a display:none panel there is nowhere to draw the error bubble, so the save button just looks dead.
The Engineer · Build desk
build
Six MariaDB versions, one real difference: the only reason to leave 10.6 is the July 2026 clock1 distinct publisher
build
WooCommerce catalog mode: the price you hid is still sitting in eight places1 distinct publisher
build
Forty animated backgrounds, one battery budget: how Pairly rations frames on old Android1 distinct publisher
build
Return post IDs and get out of the way: the one search plugin decision you live with1 distinct publisher
Compiled by The EngineerSomething wrong?How this is made
The detail that makes the fix safe is what `novalidate` leaves alone. It suppresses only the browser's automatic block-and-bubble behaviour; `required` and `pattern` keep constraining, and both `checkValidity()` and the `:invalid` pseudo-class keep reporting [9]. The markup stays the source of truth about what is mandatory. Only the job of rendering the failure moves into script [8].
The modal splits into three panels, and only one is visible at a time. At the moment the user clicks save, two of the three are sitting under `display: none` [3], which puts roughly two thirds of the form's inputs in a subtree with no box for the browser to anchor a bubble to [15]. Before the tabs, every field shared one screen, so the assumption that an invalid field is visible held by accident [7].
The ordering inside the replacement handler is the part I would not cut in review. It calls `preventDefault()`, runs `checkValidity()`, takes the first `:invalid` element, walks up to its `.site-tab-content` ancestor, and switches to the tab named in that element's `data-tab` attribute [10]. Then it waits one frame through `requestAnimationFrame` before calling `focus()` and `reportValidity()`, because focus and scrolling may not work in the same turn as the tab switch [11]. Skip the frame and you get the old symptom back with extra steps: the tab flips, the bubble never lands.
The SSH profile rule is where querying the DOM beats maintaining a list. The modal carries an "Update via browser only (no SSH)" checkbox, and leaving it unchecked makes selecting an SSH profile mandatory [13]. The toggle handler does that by writing the attribute at runtime: browser-only clears the select's value and calls `removeAttribute('required')`, otherwise it calls `setAttribute('required', '')` [14]. So the constrained set is a property of the current state, not of the template, and `querySelector(':invalid')` [10] tracks it for free where a hand-kept array of field IDs would drift.
This bug needs a container removed from layout, a constrained control inside it, and reliance on the browser's default blocking to report the failure. Miss any one and this is not your bug. If you already intercept submit and run your own validation, hiding panels costs you nothing new. If you let the platform do it, the free validation stops covering the parts of the form you chose not to show, and the user gets a button that does nothing, with no error text and no clue which tab holds the problem [4].
The writeup demonstrates the failure with `display: none` specifically [3][6]. I would not assume the other ways of hiding a panel behave identically without checking each one, because the mechanism here is about whether there is a rendered box to point at, and different hiding techniques answer that question differently.</body_markdown> </invoke>
Ranked by verification strength, evidence, and original report placement.
A site edit modal accumulated fields including site name, category, SSH connection details and WordPress install location, until editing anything meant scrolling up and down a single long form.
The form was split into three tabs, "Registration info," "SSH," and "WordPress info," and that change broke form submission itself in a way that was hard to spot at first.
Each tab's fields live in a div with class site-tab-content and a data-tab attribute, with CSS rules .site-tab-content { display: none; } and .site-tab-content.active { display: block; }.
When a required field sat in a tab that was not currently active and the user left it empty while saving from a different tab, clicking the save button did nothing and no error message appeared.
HTML5 form validation works by having the browser automatically block the submit event whenever a constrained field such as required fails, then focusing that field and showing its standard validation bubble, equivalent to calling reportValidity().
When the failing field sits inside a tab hidden with display: none, the browser has nowhere to anchor the error bubble; it still blocks the submit but cannot visualise the error, so it stops with no visible feedback and looks like a button that does not respond.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 27, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Single first-party walkthrough with reproducible code
Every claim traces to one dev.to post, but that post supplies the actual CSS, the saveSite() handler and toggleSSHFields() listings, so the mechanism and the fix are independently reproducible by any reader. What is missing is corroboration: no second source, no cross-browser test matrix, and no specification citation behind the assertion that a display:none field leaves the browser with nowhere to anchor its bubble.
No adoption signal
The source describes one internal admin modal in the author's own tool. There is no release, version, download count, usage disclosure, benchmark, or third-party uptake evidence in the cluster, so adoption cannot be measured without inventing facts.
Claims scoped to what the code shows
The post's assertions stay within the demonstrated scope: a specific regression, an explained mechanism, and a fix reproduced in code, with an explicit caveat that novalidate does not disable the constraints themselves. It makes no performance, scale, or novelty claims and does not generalize beyond 'tabs break an implicit visibility assumption', so stated significance is roughly aligned with the evidence presented.
Low: personal engineering note, no product being sold
The author writes about their own WordPress site-management tool on a developer-blogging platform, so there is a mild reputational and audience-building incentive to present the debugging story as a clean lesson learned. There is no vendor, sponsor, pricing, hiring, or fundraising angle in the cluster, and no competing product is disparaged.
Moderate: technically checkable but single-sourced
Confidence is limited by a one-publisher, one-source cluster with no independent verification and no adoption data. It is lifted by the specificity and self-consistency of the material: quoted CSS, two full JavaScript functions, and a mechanism that any reader can test in a browser, plus claims that align with widely documented Constraint Validation API behavior as described in the post itself.