I’ve put an example of how you could do this using flexbox in this codepen, but for completeness here’s the HTML and CSS from it:
<form method="post">
<input type="hidden" name="next" value="{{ next }}" />
<div class="form-error">Errors here</div>
<div class="form-row">
<label for="input1">My first label which is long</label>
<div class="form-input">
<input type="text" id="input1">
</div>
</div>
<div class="form-row">
<label for="input2">Second label</label>
<div class="form-input">
<input type="text" id="input2">
</div>
</div>
<div class="form-error">More errors here</div>
<p><button type="submit">Register</button></p>
</form>
.form-row {
display: flex;
margin-bottom: 20px;
}
.form-row label {
width: 120px;
text-align: right;
margin-right: 10px
}
.form-input {
width: 200px;
}
.form-input input {
width: 100%;
}
And it looks like this:
So to adapt that HTML for your template:
{% extends 'base.html' %}
{% block content %}
<h1>Register</h1>
<div class="form-container">
<form method="post">
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}" />
<div class="form-error">{{ form.non_field_errors }}</div>
{% for f in form %}
<div class="form-row">
<label for="{{ f.id_for_label }}">{{ f.label }}</label>
<div class="form-input">
{{ f }}
<div class="form-error">{{ f.errors }}</div>
</div>
</div>
{% endfor %}
<p><button type="submit">Register</button></p>
</form>
</div>
{% endblock %}
Notes:
- I renamed
.rowto.form-rowso it’s a bit more specific, and moved it within theforloop. .form-containerisn’t used in my styles so you could do without it unless you want to apply styling to the outside of the form- The extra
.form-inputdiv is required to keep things lined up. - You’ll need to loop through both
form.non_field_errorsandf.errorsto display each error separately if you want to display them nicely - I’ll leave that to you!
For things like this I often find it useful to look at a CSS framework and see how they do it. For example, Bootstrap 5’s horizontal forms.
