The GOV.UK Design System is a toolkit and a set of guidelines for creating sites and services for Her Majesty's Government which are clear and consistent and accessible. Services from the Met Office to the Government Property Agency all have a similar user experience which makes life easier for developers and citizens alike.
The HTML and CSS classes in the toolkit are very easy to use. However the result is a bit "wordy". Take the markup for a single text field with a single validation error (reformatted for readability):
You do get a lot for your money though. You have a set of standard styles for everything. The Aria attributes are excellent too - everything in the Design System is designed for accessibility. That takes a lot of guesswork out of the process of designing forms and ensures everything is designed and presented to a high standard.
However, this is quite a bit different from the basic HTML rendered by Django:
Ignoring the tags, clearly the structure is different. That's a problem because it means that forms have to be laid out explicitly in a template:
However it gets worse. You can't just lay out the fields in form. The problem is the markup for accessibility and error reporting. All the help text and error messages cross-reference each other. Django, out of the box, is simply not designed to handle that.
There is a straightforward solution - write our own templates for every type of form widget. That way we can support the Design System markup with 100% accuracy. That's a lot of work. I mean, a LOT of work. That also means that work has to be repeated for each project. Unless... Unless there was an easy way to share the templates. Enter, django-crispy-forms
Django-crispy-forms was designed to give you a high level of control
over how your forms is laid out. With the FormHelper
and layout
classes you can organise the fields exactly how you want
them. However, for us, the secret ingredients are the template packs.
Each pack is a complete set of templates for rendering all the
fields in a form, from simple CharFields
through to MultiValueFields
that allow you to add your own custom widgets. django-crispy-forms has
template packs for Bootstrap 3 & 4. There are also template packs for
Foundation, Materialize and others.
The essential beauty of the template pack approach is that you don't have to recreate the wheel with an entirely new rendering system for Design System forms with all the attendant problems of support and getting it adopted. Instead, thanks to the excellent instructions, you write a basic set of templates, package them up so they can be easily installed and you are done. My lords, ladies and gentlemen I give you, crispy-forms-gds.
Now when building GOV.UK services using Django all the work of rendering fields, with cross referenced identifiers and the rather daunting Error summary is reduced to this:
That's as complex as your template gets. No more writing HTML. The crispy-forms-gds templates handle all the markup. You get 100% compliance with the Design System style guide and accessibility baked right in with no extra work on your part. It's all fully tested so you don't have to.
crispy-forms-gds supports all the Components in the Design System. The one exception is the Summary list is which is not really intended for forms. The package also includes a production ready template that you can drop right into your project and start creating Design System compliant pages on day one.
The package is available on PyPI however if you checkout the source from Github then you also get a full demo site with sample forms showing how easy it is to add each of the Design System Components to a form.
This project is going to save us a lot of time. crispy-forms-gds is Open Source and freely available so we hope it will save you some time too.