[Django] #36828: Django form fields render into invalid HTML

7 views
Skip to first unread message

Django

unread,
Dec 26, 2025, 10:43:02 AM12/26/25
to django-...@googlegroups.com
#36828: Django form fields render into invalid HTML
--------------------------------+--------------------------------------
Reporter: Johannes Maron | Type: Bug
Status: new | Component: Forms
Version: dev | Severity: Normal
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------------------------
Howdy,

Django 6 introduced unannounced changes to the default form rendering.
Forms render with a fieldset, not a label, by default now.

I just noticed that fields render a `for`-attribute into a `legend`-tag.
This isn't valid HTML5 according to spec: https://html.spec.whatwg.org
/#the-legend-element

Furthermore, the use of a fieldset/legend replaces the `label`-tag.
However, input labels are required as of WCAG 2.1.

Since Django must be WCAG2.2 AAA compliant, we might even want to patch
all supported versions.

This bug was introduced only in Django 6.0, which is wild, since the
release notes don't even mention any rendering changes. After some
research, the change was introduced in #35892. I will open a separate
issue about the missing release documentation and breaking change.

Cheers!
Joe
--
Ticket URL: <https://code.djangoproject.com/ticket/36828>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 26, 2025, 10:57:22 AM12/26/25
to django-...@googlegroups.com
#36828: Django form fields render into invalid HTML
--------------------------------+--------------------------------------
Reporter: Johannes Maron | Owner: (none)
Type: Bug | Status: new
Component: Forms | Version: dev
Severity: Normal | Resolution:
Keywords: accessibility | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------------------------
Changes (by Johannes Maron):

* keywords: => accessibility

--
Ticket URL: <https://code.djangoproject.com/ticket/36828#comment:1>

Django

unread,
Dec 26, 2025, 11:00:34 AM12/26/25
to django-...@googlegroups.com
#36828: Django form fields render into invalid HTML
--------------------------------+--------------------------------------
Reporter: Johannes Maron | Owner: (none)
Type: Bug | Status: new
Component: Forms | Version: dev
Severity: Normal | Resolution:
Keywords: accessibility | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------------------------
Description changed by Johannes Maron:

Old description:

> Howdy,
>
> Django 6 introduced unannounced changes to the default form rendering.
> Forms render with a fieldset, not a label, by default now.
>
> I just noticed that fields render a `for`-attribute into a `legend`-tag.
> This isn't valid HTML5 according to spec: https://html.spec.whatwg.org
> /#the-legend-element
>
> Furthermore, the use of a fieldset/legend replaces the `label`-tag.
> However, input labels are required as of WCAG 2.1.
>
> Since Django must be WCAG2.2 AAA compliant, we might even want to patch
> all supported versions.
>
> This bug was introduced only in Django 6.0, which is wild, since the
> release notes don't even mention any rendering changes. After some
> research, the change was introduced in #35892. I will open a separate
> issue about the missing release documentation and breaking change.
>
> Cheers!
> Joe

New description:

Howdy,

Django 6 introduced unannounced changes to the default form rendering.
Forms render with a fieldset, not a label, by default now.

I just noticed that fields render a `for`-attribute into a `legend`-tag.
This isn't valid HTML5 according to spec: https://html.spec.whatwg.org
/#the-legend-element

Furthermore, the use of a fieldset/legend replaces the `label`-tag.
However, input labels are required as of WCAG 2.1.

Since Django must be WCAG2.2 AAA compliant, we might even want to patch
all supported versions. However, this would mean shippping a rendering
change in a bugfix.

My current impulse would be to drop the `for` attribute in all supported
versions for valid HTML and to enforce labels for WCAG compliance in 6.1

Cheers!
Joe

--
--
Ticket URL: <https://code.djangoproject.com/ticket/36828#comment:2>

Django

unread,
Dec 26, 2025, 11:02:39 AM12/26/25
to django-...@googlegroups.com
#36828: Django form fields render into invalid HTML
-------------------------------------+-------------------------------------
Reporter: Johannes Maron | Owner:
| Youngkwang Yang
Type: Bug | Status: assigned
Component: Forms | Version: dev
Severity: Normal | Resolution:
Keywords: accessibility | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Youngkwang Yang):

* owner: (none) => Youngkwang Yang
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36828#comment:3>

Django

unread,
Dec 26, 2025, 11:15:13 AM12/26/25
to django-...@googlegroups.com
#36828: Django form fields render into invalid HTML
-------------------------------------+-------------------------------------
Reporter: Johannes Maron | Owner:
| Youngkwang Yang
Type: Bug | Status: assigned
Component: Forms | Version: dev
Severity: Normal | Resolution:
Keywords: accessibility | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Youngkwang Yang):

This looks similar to #36724 (fixed in PR
https://github.com/django/django/pull/20080).
could you check which version you're testing with?
--
Ticket URL: <https://code.djangoproject.com/ticket/36828#comment:4>

Django

unread,
Dec 26, 2025, 11:56:08 AM12/26/25
to django-...@googlegroups.com
#36828: Django form fields render into invalid HTML
-------------------------------------+-------------------------------------
Reporter: Johannes Maron | Owner:
| Youngkwang Yang
Type: Bug | Status: assigned
Component: Forms | Version: dev
Severity: Normal | Resolution:
Keywords: accessibility | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Johannes Maron):

Thanks! Yes, that does resolve half of the issue. We have correct HTML,
but the WCAG violation remains.
--
Ticket URL: <https://code.djangoproject.com/ticket/36828#comment:5>

Django

unread,
Dec 26, 2025, 12:00:02 PM12/26/25
to django-...@googlegroups.com
#36828: Django form fields render into invalid HTML
-------------------------------------+-------------------------------------
Reporter: Johannes Maron | Owner:
| Youngkwang Yang
Type: Bug | Status: assigned
Component: Forms | Version: dev
Severity: Normal | Resolution:
Keywords: accessibility | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Johannes Maron:

Old description:

> Howdy,
>
> Django 6 introduced unannounced changes to the default form rendering.
> Forms render with a fieldset, not a label, by default now.
>
> I just noticed that fields render a `for`-attribute into a `legend`-tag.
> This isn't valid HTML5 according to spec: https://html.spec.whatwg.org
> /#the-legend-element
>
> Furthermore, the use of a fieldset/legend replaces the `label`-tag.
> However, input labels are required as of WCAG 2.1.
>
> Since Django must be WCAG2.2 AAA compliant, we might even want to patch
> all supported versions. However, this would mean shippping a rendering
> change in a bugfix.
>
> My current impulse would be to drop the `for` attribute in all supported
> versions for valid HTML and to enforce labels for WCAG compliance in 6.1
>
> Cheers!
> Joe

New description:

Howdy,

I noticed Django sometimes replaces the label with a fieldset tag.
However, input labels are required as of WCAG 2.1; see also:
https://www.w3.org/TR/WCAG21/#labels-or-instructions

Since Django must be WCAG2.2 AAA compliant, we might even want to patch
all supported versions. However, this would mean shipping a rendering
change in a bugfix.

My current impulse would be to enforce labels for WCAG compliance in 6.1,
since shipping a rendering change within a bug fix release might result
into more issues for users.

Cheers!
Joe

--
--
Ticket URL: <https://code.djangoproject.com/ticket/36828#comment:6>
Reply all
Reply to author
Forward
0 new messages