Skip to content

Label Layout

TIP

You can set the label layout and component layout styles using wrap

Ant-design-vue Grid Layout Col props

Configuration Method

In FormCreate, you can set the layout rules for labels and component containers through the rule.wrap configuration item. Ant Design Vue uses labelCol and wrapperCol to configure the grid layout of labels and component containers.

js
const rule = {
    type: 'input',
    field: 'username',
    title: 'Username',
    wrap: {
        labelCol: { span: 6 },      // Label takes up 6 columns
        wrapperCol: { span: 18 }    // Component container takes up 18 columns
    }
}

Configuration Parameters

labelCol

Grid configuration for the label container, supports all Col component properties.

MemberDescriptionTypeDefault
offsetNumber of grid columns to offset on the left side, no grid can be placed in the offset areanumber0
orderGrid order, effective in flex layout modenumber0
pullNumber of grid columns to move leftnumber0
pushNumber of grid columns to move rightnumber0
spanNumber of grid columns occupied, equivalent to display: none when 0number-
xs<576px responsive grid, can be a number or an object containing other propertiesnumber|object-
sm≥576px responsive grid, can be a number or an object containing other propertiesnumber|object-
md≥768px responsive grid, can be a number or an object containing other propertiesnumber|object-
lg≥992px responsive grid, can be a number or an object containing other propertiesnumber|object-
xl≥1200px responsive grid, can be a number or an object containing other propertiesnumber|object-
xxl≥1600px responsive grid, can be a number or an object containing other propertiesnumber|object-

wrapperCol

Grid configuration for the component container, supports all Col component properties. Parameters are the same as labelCol.

Layout Examples

Basic Layout

Default Layout (No wrap setting)

js
const rule = {
    type: 'input',
    title: 'Product Name',
    field: 'goods_name',
    // If wrap is not set, uses global default configuration
}

Equal Distribution Layout (Label and component each occupy half)

js
const rule = {
    type: 'input',
    title: 'Product Name',
    field: 'goods_name',
    wrap: {
        labelCol: { span: 12 },      // Label takes up 12 columns
        wrapperCol: { span: 12 }     // Component takes up 12 columns
    }
}

Label takes up 1/4, component takes up 3/4

js
const rule = {
    type: 'input',
    title: 'Product Name',
    field: 'goods_name',
    wrap: {
        labelCol: { span: 6 },       // Label takes up 6 columns (1/4)
        wrapperCol: { span: 18 }     // Component takes up 18 columns (3/4)
    }
}

Label takes up 1/3, component takes up 2/3

js
const rule = {
    type: 'input',
    title: 'Product Name',
    field: 'goods_name',
    wrap: {
        labelCol: { span: 8 },       // Label takes up 8 columns (1/3)
        wrapperCol: { span: 16 }     // Component takes up 16 columns (2/3)
    }
}

Only Set labelCol (wrapperCol automatically calculated)

js
const rule = {
    type: 'input',
    title: 'Product Name',
    field: 'goods_name',
    wrap: {
        labelCol: { span: 8 }        // Only set label, component automatically takes up remaining space
    }
}

Responsive Layout

Responsive Label and Component Layout

js
const rule = {
    type: 'input',
    title: 'Product Name',
    field: 'goods_name',
    wrap: {
        labelCol: {
            xs: { span: 24 },   // <576px label takes up full row
            sm: { span: 12 },   // ≥576px label takes up half
            md: { span: 8 },    // ≥768px label takes up 1/3
            lg: { span: 6 },    // ≥992px label takes up 1/4
        },
        wrapperCol: {
            xs: { span: 24 },   // <576px component takes up full row
            sm: { span: 12 },   // ≥576px component takes up half
            md: { span: 16 },   // ≥768px component takes up 2/3
            lg: { span: 18 },   // ≥992px component takes up 3/4
        }
    }
}

Simplified Responsive Configuration

js
const rule = {
    type: 'input',
    title: 'Product Name',
    field: 'goods_name',
    wrap: {
        labelCol: {
            xs: 24,   // <576px label takes up full row
            sm: 12,   // ≥576px label takes up half
            md: 8,    // ≥768px label takes up 1/3
            lg: 6,    // ≥992px label takes up 1/4
        }
    }
}

Mixed Layout

Different Fields Use Different Layouts

js
const rule = [
    {
        type: 'input',
        title: 'Product Name',
        field: 'goods_name',
        wrap: {
            labelCol: { span: 6 },
            wrapperCol: { span: 18 }
        }
    },
    {
        type: 'input',
        title: 'Product Price',
        field: 'price',
        wrap: {
            labelCol: { span: 8 },
            wrapperCol: { span: 16 }
        }
    },
    {
        type: 'input',
        title: 'Product Description',
        field: 'description',
        props: {
            type: 'textarea',
        },
        wrap: {
            labelCol: { span: 4 },
            wrapperCol: { span: 20 }
        }
    }
]

Practical Application Scenarios

Form Layout Optimization

js
const rule = [
    {
        type: 'input',
        title: 'Product Name',
        field: 'goods_name',
        validate: [
            { required: true, message: 'Please enter product name' }
        ],
        wrap: {
            labelCol: { span: 6 },
            wrapperCol: { span: 18 }
        }
    },
    {
        type: 'select',
        title: 'Product Category',
        field: 'category',
        options: [
            { value: '1', label: 'Electronics' },
            { value: '2', label: 'Clothing & Accessories' },
        ],
        wrap: {
            labelCol: { span: 6 },
            wrapperCol: { span: 18 }
        }
    },
    {
        type: 'input-number',
        title: 'Product Price',
        field: 'price',
        wrap: {
            labelCol: { span: 6 },
            wrapperCol: { span: 18 }
        }
    },
    {
        type: 'input',
        title: 'Product Description',
        field: 'description',
        props: {
            type: 'textarea',
            rows: 4,
        },
        wrap: {
            labelCol: { span: 4 },
            wrapperCol: { span: 20 }  // Description field gives component more space
        }
    }
]

Mobile Device Adaptation

js
const rule = {
    type: 'input',
    title: 'Phone Number',
    field: 'phone',
    wrap: {
        labelCol: {
            xs: { span: 24 },  // Mobile: label takes up full row
            sm: { span: 6 },    // Tablet and above: label takes up 6 columns
        },
        wrapperCol: {
            xs: { span: 24 },   // Mobile: component takes up full row
            sm: { span: 18 },   // Tablet and above: component takes up 18 columns
        }
    }
}

Using with Col Layout

js
const rule = [
    {
        type: 'row',
        native: true,
        children: [
            {
                type: 'col',
                props: { span: 12 },
                native: true,
                children: [
                    {
                        type: 'date-picker',
                        title: 'Activity Date',
                        field: 'section_day',
                        props: {
                            picker: 'date',
                            range: true
                        },
                        wrap: {
                            labelCol: { span: 8 }  // Set label layout inside col
                        }
                    }
                ]
            },
            {
                type: 'col',
                props: { span: 12 },
                native: true,
                children: [
                    {
                        type: 'input-number',
                        title: 'Sort',
                        field: 'sort',
                        wrap: {
                            labelCol: { span: 8 }
                        }
                    }
                ]
            }
        ]
    }
]

Using offset for Offset

js
const rule = {
    type: 'input',
    title: 'Product Name',
    field: 'goods_name',
    wrap: {
        labelCol: { 
            span: 6,
            offset: 2  // Label left offset of 2 columns
        },
        wrapperCol: { span: 16 }
    }
}

Notes

  1. Property Name: Ant Design Vue uses labelCol and wrapperCol, which differs from other frameworks (such as Arco Design's labelColProps and wrapperColProps)
  2. Grid System: Ant Design Vue uses a 24-column grid system. The sum of labelCol.span and wrapperCol.span is usually 24
  3. Automatic Calculation: If only labelCol is set, wrapperCol is automatically calculated as 24 - labelCol.span
  4. Responsive: Layout adaptation for different screen sizes can be achieved through responsive configuration
  5. Global Configuration: Default labelCol and wrapperCol can be set in the form's global configuration

Tips

  • The sum of span values for labelCol and wrapperCol is usually 24
  • You can set only labelCol, and wrapperCol will be automatically calculated
  • Responsive layout can make forms display well on different devices

FormCreate is an open-source project released under the MIT License. Free for personal and commercial use.