layout takes three values and they are not interchangeable. Each one has a width below which it stops reading as a form.
- horizontal is the default: label in a column beside the control, aligned down the page. It reads well on a wide settings page and breaks on a narrow one, because the label column and the control column each get half of a space that was already tight. The column widths are labelCol and wrapperCol, which take Grid Col props, so pass a responsive object when the layout only works above md.
- vertical puts the label above the control and gives the control the full width. It is the safe choice for anything narrow, anything in a drawer, and any form with long labels. It costs vertical space, so a twenty-field form becomes a long scroll.
- inline flows the items on one line. It is for a filter bar of three or four short fields. It stops working once a field can show an error, because the message appears under one item and shifts the row.
labelAlign (left or right, default right) only means anything under horizontal. labelWrap lets a long label wrap instead of being clipped, and an individual item can override the form with its own layout, which takes horizontal or vertical only.
One stacked item needs full-width columns. layout="vertical" on a single Form.Item stacks its label, but the item still takes the form's labelCol and wrapperCol. Give it { span: 24 } for both so the control spans the form.