Skip to main content

Accessibility

Screen Reader Only

.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
white-space: nowrap;
border-width: 0;
clip-path: polygon(0 0, 0 0, 0 0);
}

.not-sr-only {
position: static;
width: auto;
height: auto;
padding: 0;
margin: 0;
overflow: visible;
white-space: normal;
clip-path: none;
}

Focusable Areas

Focusable areas:

  • Elements whose tabindex value is not null.
  • The shapes of area elements in an image map.
  • The sub-widgets of elements: e.g. video controls.
  • The scrollable regions of elements.
  • The viewport of a Document.
  • User agent focusable area.

Keyboard Styles

添加键盘访问样式:

  • outline.
  • :focus-visible.
  • :focus.
HTML Order vs CSS Order

HTML source order vs CSS display order:

float/absolute/flex/grid CSS display order can't change HTML source tab order.

Graceful Degradation

Write old browser css code, then write modern browser css code:

.grid {
display: flex;

/* old browser will ignore this rule */
display: grid;
}

ARIA

DPR

Device pixel ratio (DPR):

一般情况下, PC 屏幕 DPR 为 1, 1 个逻辑像素 = 1 个物理像素, 移动端 DPR 为 2 或 3, 1 个逻辑像素 = 2 或 3 个物理像素, 由此产生 移动端/Retina 屏幕 1px 边框 (pixel border) 问题:

  • 伪元素 + scale 变换.
  • border-image.
  • background-image.
  • background gradient.
  • box-shadow.
  • viewport + rem.
.scale-1px {
position: relative;
border: none;
}

.scale-1px::after {
position: absolute;
bottom: 0;
width: 100%;
height: 1px;
content: '';
background: #000;
transform: scaleY(0.5);
transform-origin: 0 0;
}

.border-image-1px {
border-width: 0 0 1px;
border-bottom: none;
border-image: url('../img/line.png') 0 0 2 0 stretch;
}

.background-image-1px {
background: url('../img/line.png') repeat-x left bottom;
background-size: 100% 1px;
}

.background-gradient-1px {
background:
linear-gradient(#000, #000 100%, transparent 100%) left / 1px 100% no-repeat,
linear-gradient(#000, #000 100%, transparent 100%) right / 1px 100% no-repeat,
linear-gradient(#000, #000 100%, transparent 100%) top / 100% 1px no-repeat,
linear-gradient(#000, #000 100%, transparent 100%) bottom / 100% 1px no-repeat;
}

.box-shadow-1px {
box-shadow: inset 0 -1px 1px -1px #c8c7cc;
}
// Change viewport scale
const scale = 1 / window.devicePixelRatio
const viewport = document.querySelector('meta[name="viewport"]')
viewport.setAttribute(
'content',
`width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`
)

// Set root font size
const docEl = document.documentElement
const fontsize = `${10 * (docEl.clientWidth / 320)}px`
docEl.style.fontSize = fontsize