Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6287679
refactor!: field baseline alignment
jouni Oct 14, 2025
36335a9
test: fix text-area unit tests
jouni Oct 14, 2025
fe014a6
fix: contain baseline alignment pseudo within the host
jouni Oct 14, 2025
dcae3e4
fix: avoid announcing alignment pseudo text content
jouni Oct 14, 2025
4f35c91
Revert "fix: contain baseline alignment pseudo within the host"
jouni Oct 14, 2025
324a0c2
fix: align button on baseline (default)
jouni Oct 14, 2025
e6b44e2
chore: add button and icons in baseline alignment dev page
jouni Oct 14, 2025
b938ffd
rework grid-rows
jouni Oct 14, 2025
daca3f2
more comprehensive test page
jouni Oct 14, 2025
baff033
test: update checkbox-group base screenshots
jouni Oct 14, 2025
1fed5a1
test: update custom-field base screenshots
jouni Oct 14, 2025
4389fc3
test: update radio-group base screenshots
jouni Oct 14, 2025
ab31b73
spicy up dev/test page
jouni Oct 15, 2025
ec4f362
fix: align horizontal group fields with text inputs when label is used
jouni Oct 15, 2025
5bebcad
chore: avoid sonarcloud warning
jouni Oct 15, 2025
a03af17
refactor: use grid-template-areas and margins
jouni Nov 6, 2025
db07aa2
update checkbox screenshots
jouni Nov 6, 2025
d31ae7f
update radio-group screenshots
jouni Nov 6, 2025
a9144a4
update combo-box screenshots
jouni Nov 6, 2025
e0022d2
update custom-field screenshots
jouni Nov 6, 2025
8ec0afe
update date-picker screenshots
jouni Nov 6, 2025
b8469ab
update date-time-picker screenshots
jouni Nov 6, 2025
8c7d49d
update mscb screenshots
jouni Nov 6, 2025
9275deb
update number-field screenshots
jouni Nov 6, 2025
071e8bf
update text-area screenshots
jouni Nov 6, 2025
9e25dfd
update text-field screenshots
jouni Nov 6, 2025
d0a60f7
update time-picker screenshots
jouni Nov 6, 2025
35d7f26
remove empty custom-field style declaration
jouni Nov 6, 2025
f9a56e6
chore: update stylelint config
web-padawan Nov 6, 2025
998e174
Revert "chore: update stylelint config"
jouni Nov 7, 2025
be3c83e
fix alignment for fields without label
jouni Nov 7, 2025
9da6432
update select screenshots
jouni Nov 7, 2025
2a8ea4c
fix lint error
jouni Nov 7, 2025
ef327fe
update custom-field screenshots
jouni Nov 7, 2025
b43e335
update checkbox-group screenshots
jouni Nov 7, 2025
0e61edf
update radio-group screenshots
jouni Nov 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
282 changes: 282 additions & 0 deletions dev/baseline.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Field Baseline Alignment</title>
<script type="module" src="./common.js"></script>

<script type="module">
import '@vaadin/text-field';
import '@vaadin/text-area';
import '@vaadin/checkbox';
import '@vaadin/radio-group';
import '@vaadin/checkbox-group';
import '@vaadin/select';
import '@vaadin/custom-field';
import '@vaadin/number-field';
import '@vaadin/date-time-picker';
import '@vaadin/icon';
import '@vaadin/icons';
import '@vaadin/button';

const select = document.querySelectorAll('vaadin-select').forEach((select) => {
select.items = [
{ label: 'A', value: 'a' },
{ label: 'B', value: 'b' },
{ label: 'C', value: 'c' },
];
});

document.querySelector('#flex').addEventListener('change', (e) => {
document.documentElement.classList.toggle('use-flex', e.target.checked);
});
</script>
<style>
.use-flex section {
display: flex;
align-items: baseline;
gap: 0.3em;

> * {
flex: none;
}

> span:first-child {
position: relative;
z-index: 1;

&::before {
content: "";
position: absolute;
width: 200vw;
height: 1px;
background: rgba(255, 0, 0, 0.612);
top: calc(1em + 1px);
}
}
}
</style>
</head>

<body>
<vaadin-checkbox id="flex" label="Use flex layout & show baseline"></vaadin-checkbox>
<h2 class="heading">Plain</h2>
<section>
<span>Inline text</span>
<vaadin-button>
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
Button
</vaadin-button>
<vaadin-checkbox checked></vaadin-checkbox>
<vaadin-text-field placeholder="Text Field">
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
</vaadin-text-field>
<vaadin-text-area placeholder="Text Area"></vaadin-text-area>
<vaadin-date-time-picker date-placeholder="Date-Time" time-placeholder="Picker"></vaadin-date-time-picker>
<vaadin-select placeholder="Select"></vaadin-select>
<vaadin-checkbox-group theme="horizontal">
<vaadin-checkbox value="a" label="A" checked></vaadin-checkbox>
<vaadin-checkbox value="b" label="B"></vaadin-checkbox>
<vaadin-checkbox value="c" label="C"></vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-checkbox-group>
<vaadin-checkbox value="a" label="A" checked></vaadin-checkbox>
<vaadin-checkbox value="b" label="B"></vaadin-checkbox>
<vaadin-checkbox value="c" label="C"></vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-radio-group>
<vaadin-radio-button value="a" label="A"></vaadin-radio-button>
<vaadin-radio-button value="b" label="B"></vaadin-radio-button>
<vaadin-radio-button value="c" label="C"></vaadin-radio-button>
</vaadin-radio-group>
<vaadin-custom-field>
<vaadin-text-field placeholder="Custom"></vaadin-text-field>
<vaadin-number-field placeholder="Field"></vaadin-number-field>
</vaadin-custom-field>
</section>

<h2 class="heading">Labels</h2>
<section>
<span>Inline text</span>
<vaadin-button>
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
Button
</vaadin-button>
<vaadin-checkbox checked label="Label"></vaadin-checkbox>
<vaadin-text-field placeholder="Text Field" label="Label that wraps on multiple lines">
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
</vaadin-text-field>
<vaadin-text-area placeholder="Text Area" label="Label"></vaadin-text-area>
<vaadin-date-time-picker date-placeholder="Date-Time" time-placeholder="Picker"
label="Label"></vaadin-date-time-picker>
<vaadin-select placeholder="Select" label="Label"></vaadin-select>
<vaadin-checkbox-group theme="horizontal" label="Label">
<vaadin-checkbox value="a" label="A" checked></vaadin-checkbox>
<vaadin-checkbox value="b" label="B"></vaadin-checkbox>
<vaadin-checkbox value="c" label="C"></vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-checkbox-group label="Label">
<vaadin-checkbox value="a" label="A" checked></vaadin-checkbox>
<vaadin-checkbox value="b" label="B"></vaadin-checkbox>
<vaadin-checkbox value="c" label="C"></vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-radio-group label="Label">
<vaadin-radio-button value="a" label="A"></vaadin-radio-button>
<vaadin-radio-button value="b" label="B"></vaadin-radio-button>
<vaadin-radio-button value="c" label="C"></vaadin-radio-button>
</vaadin-radio-group>
<vaadin-custom-field label="Label that is long but doesn't wrap">
<vaadin-text-field placeholder="Custom"></vaadin-text-field>
<vaadin-number-field placeholder="Field"></vaadin-number-field>
</vaadin-custom-field>
</section>

<h2 class="heading">Helper Texts</h2>
<section>
<span>Inline text</span>
<vaadin-button>
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
Button
</vaadin-button>
<vaadin-checkbox checked label="Label" helper-text="Description text"></vaadin-checkbox>
<vaadin-text-field placeholder="Text Field" label="Label that wraps on multiple lines"
helper-text="Description text">
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
</vaadin-text-field>
<vaadin-text-area placeholder="Text Area" label="Label" helper-text="Description text"></vaadin-text-area>
<vaadin-date-time-picker date-placeholder="Date-Time" time-placeholder="Picker" label="Label"
helper-text="Description text"></vaadin-date-time-picker>
<vaadin-select placeholder="Select" label="Label" helper-text="Description text"></vaadin-select>
<vaadin-checkbox-group theme="horizontal" label="Label" helper-text="Description text">
<vaadin-checkbox value="a" label="A" checked></vaadin-checkbox>
<vaadin-checkbox value="b" label="B"></vaadin-checkbox>
<vaadin-checkbox value="c" label="C"></vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-checkbox-group label="Label" helper-text="Description text">
<vaadin-checkbox value="a" label="A" checked></vaadin-checkbox>
<vaadin-checkbox value="b" label="B"></vaadin-checkbox>
<vaadin-checkbox value="c" label="C"></vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-radio-group label="Label" helper-text="Description text">
<vaadin-radio-button value="a" label="A"></vaadin-radio-button>
<vaadin-radio-button value="b" label="B"></vaadin-radio-button>
<vaadin-radio-button value="c" label="C"></vaadin-radio-button>
</vaadin-radio-group>
<vaadin-custom-field label="Label that is long but doesn't wrap" helper-text="Description text">
<vaadin-text-field placeholder="Custom"></vaadin-text-field>
<vaadin-number-field placeholder="Field"></vaadin-number-field>
</vaadin-custom-field>
</section>

<h2 class="heading">Helper Above Field</h2>
<section>
<span>Inline text</span>
<vaadin-button>
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
Button
</vaadin-button>
<vaadin-checkbox checked label="Label" helper-text="Description text" theme="helper-above-field">
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
</vaadin-checkbox>
<vaadin-text-field placeholder="Text Field" label="Label that wraps on multiple lines"
helper-text="Description text" theme="helper-above-field"></vaadin-text-field>
<vaadin-text-area placeholder="Text Area" label="Label" helper-text="Description text"
theme="helper-above-field"></vaadin-text-area>
<vaadin-date-time-picker date-placeholder="Date-Time" time-placeholder="Picker" label="Label"
helper-text="Description text" theme="helper-above-field"></vaadin-date-time-picker>
<vaadin-select placeholder="Select" label="Label" helper-text="Description text"
theme="helper-above-field"></vaadin-select>
<vaadin-checkbox-group theme="horizontal helper-above-field" label="Label" helper-text="Description text">
<vaadin-checkbox value="a" label="A" checked></vaadin-checkbox>
<vaadin-checkbox value="b" label="B"></vaadin-checkbox>
<vaadin-checkbox value="c" label="C"></vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-checkbox-group label="Label" helper-text="Description text" theme="helper-above-field">
<vaadin-checkbox value="a" label="A" checked></vaadin-checkbox>
<vaadin-checkbox value="b" label="B"></vaadin-checkbox>
<vaadin-checkbox value="c" label="C"></vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-radio-group label="Label" helper-text="Description text" theme="helper-above-field">
<vaadin-radio-button value="a" label="A"></vaadin-radio-button>
<vaadin-radio-button value="b" label="B"></vaadin-radio-button>
<vaadin-radio-button value="c" label="C"></vaadin-radio-button>
</vaadin-radio-group>
<vaadin-custom-field label="Label that is long but doesn't wrap" helper-text="Description text"
theme="helper-above-field">
<vaadin-text-field placeholder="Custom"></vaadin-text-field>
<vaadin-number-field placeholder="Field"></vaadin-number-field>
</vaadin-custom-field>
</section>

<h2 class="heading">Error Messages</h2>
<section>
<span>Inline text</span>
<vaadin-button>
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
Button
</vaadin-button>
<vaadin-checkbox checked label="Label" helper-text="Description text" invalid
error-message="Something is wrong"></vaadin-checkbox>
<vaadin-text-field placeholder="Text Field" label="Label that wraps on multiple lines"
helper-text="Description text" invalid error-message="Something is wrong">
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
</vaadin-text-field>
<vaadin-text-area placeholder="Text Area" label="Label" helper-text="Description text" invalid
error-message="Something is wrong"></vaadin-text-area>
<vaadin-date-time-picker date-placeholder="Date-Time" time-placeholder="Picker" label="Label"
helper-text="Description text" invalid error-message="Something is wrong"></vaadin-date-time-picker>
<vaadin-select placeholder="Select" label="Label" helper-text="Description text" invalid
error-message="Something is wrong"></vaadin-select>
<vaadin-checkbox-group label="Label" helper-text="Description text" invalid error-message="Something is wrong">
<vaadin-checkbox value="a" label="A"></vaadin-checkbox>
<vaadin-checkbox value="b" label="B"></vaadin-checkbox>
<vaadin-checkbox value="c" label="C"></vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-radio-group label="Label" helper-text="Description text" invalid error-message="Something is wrong">
<vaadin-radio-button value="a" label="A"></vaadin-radio-button>
<vaadin-radio-button value="b" label="B"></vaadin-radio-button>
<vaadin-radio-button value="c" label="C"></vaadin-radio-button>
</vaadin-radio-group>
<vaadin-custom-field label="Label that is long but doesn't wrap" helper-text="Description text" invalid
error-message="Something is wrong">
<vaadin-text-field placeholder="Custom"></vaadin-text-field>
<vaadin-number-field placeholder="Field"></vaadin-number-field>
</vaadin-custom-field>
</section>

<h2 class="heading">Mixed</h2>
<section>
<span>Inline text</span>
<vaadin-button>
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
Button
</vaadin-button>
<vaadin-checkbox checked label="Label" helper-text="Description text" invalid
error-message="Something is wrong"></vaadin-checkbox>
<vaadin-text-field placeholder="Text Field" label="Label that wraps on multiple lines">
<vaadin-icon icon="vaadin:file" slot="prefix"></vaadin-icon>
</vaadin-text-field>
<vaadin-text-area placeholder="Text Area" helper-text="Description text"></vaadin-text-area>
<vaadin-date-time-picker date-placeholder="Date-Time" time-placeholder="Picker" invalid
error-message="Something is wrong"></vaadin-date-time-picker>
<vaadin-select placeholder="Select" label="Label" invalid error-message="Something is wrong"></vaadin-select>
<vaadin-checkbox-group label="Label" theme="horizontal">
<vaadin-checkbox value="a" label="A"></vaadin-checkbox>
<vaadin-checkbox value="b" label="B"></vaadin-checkbox>
</vaadin-checkbox-group>
<vaadin-radio-group label="Label" invalid error-message="Something is wrong">
<vaadin-radio-button value="a" label="A"></vaadin-radio-button>
<vaadin-radio-button value="b" label="B"></vaadin-radio-button>
</vaadin-radio-group>
<vaadin-custom-field label="Label that is long but doesn't wrap" helper-text="Description text" invalid
error-message="Something is wrong" theme="helper-above-field">
<vaadin-text-field placeholder="Custom"></vaadin-text-field>
<vaadin-number-field placeholder="Field"></vaadin-number-field>
</vaadin-custom-field>
</section>
</body>

</html>
4 changes: 4 additions & 0 deletions packages/aura/src/size.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
--vaadin-gap-m: var(--vaadin-padding-m);
--vaadin-gap-l: var(--vaadin-padding-l);
--vaadin-gap-xl: var(--vaadin-padding-xl);

--vaadin-field-baseline-input-height: calc(
1lh + round(var(--vaadin-padding-s) / 1.4, 1px) * 2 + var(--vaadin-input-field-border-width, 1px) * 2
);
}

@media (pointer: coarse) {
Expand Down
1 change: 0 additions & 1 deletion packages/button/src/styles/vaadin-button-base-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export const buttonStyles = css`
user-select: none;
cursor: var(--vaadin-clickable-cursor);
box-sizing: border-box;
vertical-align: middle;
flex-shrink: 0;
height: var(--vaadin-button-height, auto);
margin: var(--vaadin-button-margin, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
import { field } from '@vaadin/field-base/src/styles/field-base-styles.js';
import { group } from '@vaadin/field-base/src/styles/group-base-styles.js';

export const checkboxGroupStyles = [field, group('checkbox')];
export const checkboxGroupStyles = [field, group];
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,6 @@
* Copyright (c) 2019 - 2025 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { css } from 'lit';
import { container } from '@vaadin/field-base/src/styles/container-base-styles.js';
import { field } from '@vaadin/field-base/src/styles/field-base-styles.js';

const customField = css`
.vaadin-custom-field-container {
width: 100%;
}

.inputs-wrapper {
flex: none;
}
`;

export const customFieldStyles = [field, container, customField];
export const customFieldStyles = [field];
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 13 additions & 9 deletions packages/field-base/src/styles/checkable-base-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import { css, unsafeCSS } from 'lit';
export const checkable = (part, propName = part) => css`
:host {
align-items: center;
display: inline-grid;
gap: var(--vaadin-${unsafeCSS(propName)}-gap, var(--vaadin-gap-xs) var(--vaadin-gap-s));
column-gap: var(--vaadin-${unsafeCSS(propName)}-gap, var(--vaadin-gap-s));
grid-template-columns: auto 1fr;
/*
Using minmax(auto, max-content) works around a Safari 17 issue where placing a checkbox
Expand All @@ -31,10 +30,6 @@ export const checkable = (part, propName = part) => css`
column-gap: 0;
}

.vaadin-${unsafeCSS(propName)}-container {
display: contents;
}

[part='${unsafeCSS(part)}'],
::slotted(input),
[part='label'],
Expand All @@ -58,17 +53,26 @@ export const checkable = (part, propName = part) => css`
grid-column: 1;
}

[part='label'],
[part='helper-text'],
[part='error-message'] {
margin-bottom: 0;
grid-column: 2;
width: auto;
min-width: auto;
}

[part='helper-text'],
[part='error-message'] {
margin-top: var(--_gap-s);
}

/* Baseline vertical alignment */
:host::before {
content: '\\2003';
grid-column: 1;
grid-row: 1;
width: 0;
margin: 0;
padding: 0;
border: 0;
}

/* visually hidden */
Expand Down
8 changes: 0 additions & 8 deletions packages/field-base/src/styles/container-base-styles.d.ts

This file was deleted.

Loading