-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathitem-no-justify-self.ts
More file actions
96 lines (83 loc) · 3.57 KB
/
item-no-justify-self.ts
File metadata and controls
96 lines (83 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { type RuleDescriptor, type Warning, createWarning } from './types.ts';
import {
isBlockLayoutDisplay,
isDefaultSelfAlignmentValue,
isMulticolContainer,
} from './context.ts';
import { registerRule } from './registry.ts';
const RULE_ID = 'item-no-justify-self' as const;
const warn = (fields: Omit<Warning, 'ruleId' | 'severity'>) => createWarning(RULE_ID, fields);
/**
* Child display values that do NOT generate a block-level box.
* justify-self in block layout only applies to block-level boxes (Chrome 119+).
* This covers inline-level types, table-internal types, and inline outer display types
* (inline-block, inline-flex, inline-grid) — all empirically confirmed in Chromium.
*/
function isNonBlockLevelBox(display: string): boolean {
return (
display === 'inline' ||
display === 'inline-block' ||
display === 'inline-flex' ||
display === 'inline-grid' ||
display === 'inline-table' ||
display === 'ruby' ||
display === 'table-row' ||
display === 'table-cell' ||
display === 'table-row-group' ||
display === 'table-header-group' ||
display === 'table-footer-group' ||
display === 'table-column' ||
display === 'table-column-group' ||
display === 'table-caption'
);
}
function isTableWrapperDisplay(display: string): boolean {
return display === 'table' || display === 'inline-table';
}
const rule: RuleDescriptor = {
id: RULE_ID,
label: 'justify-self outside flex/grid/block/positioned context',
requiredProperties: ['justifySelf', 'position', 'display'],
requiredParentProperties: ['display', 'columnCount', 'columnWidth'],
check(ctx) {
if (ctx.isGridItem) return [];
if (!ctx.parentStyles) return [];
const { justifySelf } = ctx.styles;
if (isDefaultSelfAlignmentValue(justifySelf)) return [];
// justify-self works on absolutely/fixed-positioned elements (Chrome 105+)
const { position } = ctx.styles;
if (position === 'absolute' || position === 'fixed') return [];
// display:contents removes the parent's box, so the child participates in the
// grandparent's formatting context. Without grandparent data we cannot determine
// if this element is effectively a flex/grid item.
if (ctx.isParentContents) return [];
// Chromium applies justify-self to children of table wrappers
// (display: table / inline-table), but not to table-internal boxes.
if (isTableWrapperDisplay(ctx.parentDisplay)) return [];
// justify-self works in block layout (Chrome 119+), but only on block-level boxes.
// Non-block-level children and multi-column containers are excluded.
if (isBlockLayoutDisplay(ctx.parentDisplay)) {
if (
!isNonBlockLevelBox(ctx.styles.display) &&
!isMulticolContainer(
ctx.parentDisplay,
ctx.parentStyles.columnCount ?? 'auto',
ctx.parentStyles.columnWidth ?? 'auto',
)
) {
return [];
}
}
return [
warn({
property: 'justify-self',
title: 'justify-self has no effect',
details: `justify-self is "${justifySelf}" but parent display is "${ctx.parentDisplay}". In Chromium, justify-self takes effect on grid items, children of table wrappers, block-level elements in block layout, or absolutely/fixed-positioned elements. It does not affect flex items or table-internal boxes.`,
suggestion:
'Use a grid parent, a table wrapper, a block-layout parent with a block-level child, or absolute/fixed positioning. Otherwise, remove justify-self.',
}),
];
},
};
registerRule(rule);
export const checkJustifySelf = rule.check;