Inline forms

The two classes that put fields on a line, which are not two names for one thing: container-inline, which core styles and which pulls every label beside its input, and form--inline, which only the themes style and which lays the items out side by side with their labels above them. Every section is rebuilt from a form of core or of a contrib module and names the file it comes from. Nothing is saved: each button says which one was pressed.

The two classes side by side

The same text field, select and button, once in a container-inline and once in a form--inline. Under the first the labels should sit beside their inputs, the whole row on one line; under the second each label stays above its input and the items line up at the foot, with the button on the baseline of the inputs rather than of the labels. If both rows look the same, one of the two classes is not being styled.

  • core/modules/system/css/components/container-inline.module.css — all core ships for container-inline
  • core/themes/starterkit_theme/css/components/inline-form.css — the form--inline of a theme generated from starterkit
  • core/themes/olivero/css/components/form.css — the form--inline of Olivero

A filter in a details element

The commonest use of container-inline in core: on a details element, around one field and the buttons that act on it. The field title is invisible, so the summary of the details is the only label. Core makes an exception for .details-wrapper, which stays a block, so the body of the details opens under its summary rather than beside it.

Filter aliases
Update options
  • core/modules/path/src/Form/PathFilterForm.php — the filter above the list of URL aliases
  • core/modules/comment/src/Form/CommentAdminOverview.php — the bulk operation above the list of comments
  • web/modules/contrib/devel/src/Form/ConfigsList.php — the filter of the config list
  • web/modules/contrib/redirect/modules/redirect_404/src/Form/RedirectFix404Form.php — the filter of the 404 log
  • web/modules/contrib/webform/src/Form/WebformEntityFilterForm.php — the filter above the webform listing, and four more filter forms of webform

A field and the button it belongs to

A plain container made inline around a field whose title is visible, and the button that submits it: the label, the input and the button all on one line. Devel puts its user autocomplete in one; a text field stands in for it here, because an autocomplete on a public page answers whoever asks.

  • core/modules/search/src/SearchPageListBuilder.php — adding a search page, on the search settings
  • web/modules/contrib/devel/src/Form/SwitchUserForm.php — the switch user block

A composite fieldset

One setting made of two inputs, in a fieldset carrying container-inline, fieldgroup and form-composite. Both inputs have invisible titles, so the legend labels the pair, and in the second a #field_prefix reads into them as a sentence. The limit of the first is hidden through #states while the select says unlimited, which the row has to survive without leaving a gap.

Allowed number of values
Frequency
Run every
  • core/modules/field_ui/src/Form/FieldStorageConfigEditForm.php — getCardinalityForm(), on the settings of every field
  • web/modules/contrib/backup_migrate/src/Form/ScheduleForm.php — the frequency of a backup schedule

A sentence of selects

The views wizard builds its display settings as a fieldset with container-inline and fieldset-no-legend, so the legend is there for a screen reader and the titles of the selects read as one line: Display format: Unformatted list of: teasers. A second select that has only one option is replaced by plain text, which has to sit on the same baseline as the select before it.

Page display settings
Block display settings
of fields
  • core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php — the page and block display settings of admin/structure/views/add

A label beside its value

container-inline on the wrapper of a single form item, through #wrapper_attributes, rather than on a container around several. The label goes beside what it labels and the items stay one to a line, which makes a list of label and value pairs. Content moderation does it with an item and a select; Webform with a column of items, and an inline margin of 0 on each that is left out here, so the theme decides the space between them.

Draft
Action
completed
Flagged/Starred
Unlocked
A note long enough to wrap onto a second line under its label, which is where a value that does not fit beside the label ends up.
  • core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php — the moderation state of a content form
  • web/modules/contrib/webform/src/Plugin/WebformHandler/ActionWebformHandler.php — the summary of an action handler, and of the email, remote post and scheduled email handlers
  • web/modules/contrib/entity_embed/src/Form/EntityEmbedDialog.php — the same, on both #wrapper_attributes and #attributes

Only the buttons inline

The log message filter puts container-inline on its actions element and nowhere else. The two lists above it are left to stack, and the class has nothing to make inline but the buttons -- so what it changes is the space an actions element takes at the foot of a form, which an inline one is expected to give back.

Filter log messages
  • core/modules/dblog/src/Form/DblogFilterForm.php — the filter of admin/reports/dblog
  • core/modules/locale/src/Form/TranslateFilterForm.php — the same, on the filter of the translation interface
  • core/modules/migrate/src/Form/MessageForm.php — the same, on the filter of migration messages

On the inputs as well

Geofield builds a coordinate as orientation, degrees, minutes and seconds, and puts container-inline on the container and again on every input, with the unit after each one as a #suffix. The class on an input is harmless to core, which only styles the divs and labels under it, but a theme that makes a flex container of .container-inline makes one of each input too; this theme leaves inputs out of the rule for that reason. The original gives each input an empty title; they are invisible ones here.

Latitude
°
'
"
Longitude
°
'
"
  • web/modules/contrib/geofield/src/Element/GeofieldDms.php — processComponent(), the degrees, minutes and seconds widget

Everything inside goes inline

The core rule is a descendant selector, .container-inline div, so it reaches every div at any depth: the description of a field, the wrapper of a checkbox, a container nested inside. None of the forms above has a description under a field in an inline container, and this is why -- the description is pulled onto the line beside its input. Webform wraps a date and time element in a div carrying container-inline and form-item, so the label goes beside the two inputs and the block keeps the spacing of a field.

A description that would normally sit under its input.

Open

  • core/modules/system/css/components/container-inline.module.css — .container-inline div, .container-inline label
  • web/modules/contrib/webform/src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php — the open and close dates of a scheduled webform field

Width by height

The image field puts its maximum and minimum dimensions in an item whose two numbers are wrapped in a form--inline through #prefix and #suffix, the div opened before the first and closed after the second. The titles of the numbers are invisible, the item title labels the pair, and each number has a #field_suffix -- the × between them and the unit after them -- that has to stay on the line with its input. The description of the item comes after the row.

×
pixels
The maximum allowed image size expressed as WIDTH×HEIGHT (e.g. 640×480). Leave blank for no restriction.
×
pixels
The minimum allowed image size expressed as WIDTH×HEIGHT (e.g. 640×480). Leave blank for no restriction.
  • core/modules/image/src/Plugin/Field/FieldType/ImageItem.php — fieldSettingsForm(), on the settings of every image field
  • core/modules/editor/src/EditorImageUploadSettings.php — the maximum dimensions of an image uploaded in a text editor

Controls above a list

A search and a select in a form--inline, both with visible titles, and no button: the list below them is filtered as they change. Views UI builds the container from #theme_wrappers rather than a container element. Field group puts a single select in its form--inline, so a row of one is a shape the class has to keep tidy as well.

  • core/modules/views_ui/src/Form/Ajax/AddHandler.php — the controls of the dialog that adds a field, filter or sort
  • core/modules/field_ui/src/Form/FieldStorageReuseForm.php — re-using an existing field
  • web/modules/contrib/field_group/src/Form/FieldGroupAddForm.php — adding a field group

Exposed filters

The shape most people meet form--inline in. No module puts it on an exposed form: the themes do, Olivero by altering the form and starterkit by wrapping the template in a div that carries it. So the actions element is an item of the row, and the row decides where it goes -- starterkit clears it onto a line of its own; this theme keeps it on the line, aligned with the foot of the inputs.

  • core/themes/olivero/src/Hook/OliveroHooks.php — formViewsExposedFormAlter(), which adds the class to the form
  • core/themes/starterkit_theme/templates/views/views-exposed-form.html.twig — the div it wraps the form in
  • web/modules/contrib/better_exposed_filters/templates/bef-radios.html.twig — the same class on a set of radios shown inline

The parts of one value

Widgets whose inputs are the parts of a single value, laid out on a row with form--inline: the inline layout of the name field, with a visible title on every part and inputs of different widths; the height element of Webform, two selects with invisible titles; and the hierarchy widget, a parent and a weight. The row has to wrap without leaving a part stranded.

feet
inches
  • web/modules/contrib/name/src/Hook/WidgetLayoutHooks.php — the inline layout of the name widget
  • web/modules/contrib/webform/src/Element/WebformHeight.php — the height element
  • web/modules/contrib/entity_hierarchy/src/Plugin/Field/FieldWidget/EntityReferenceHierarchySelect.php — the parent and weight of a hierarchy reference