默认只显示问题 —— 先自己在心里答一遍,再展开对答案。答不上来就标「不会」,下次抽认卡会先抽它。Only the question shows by default. Answer it in your head first, then open the answer. Mark the ones you miss; the flashcard round puts those first.
0 / 105道自评过self-assessed
0会Got it0模糊Shaky0不会No idea105还没做Not seen
正在读这台浏览器里的标记…Reading your marks from this browser…
标记不是打分,是给下一轮排队Marks are a queue, not a score
标「不会」的题会排到抽认卡最前面,标「会」的进低频池排最后。所以别客气 —— 觉得答得磕磕巴巴就标「模糊」。准备好了就去抽认卡。“No idea” jumps to the front of the next round; “got it” drops to the back. So be honest — if it came out shaky, mark it shaky. Then go run a flashcard round.
找一道题Find one按方向、掌握状态筛Filter by topic and markCSSCSS
In one line: every element is a box with four layers from the inside out: content → padding → border → margin.
What is actually being tested is “what exactly does width measure?”
box-sizing
width: 200px means
with padding: 20px it occupies
content-box (default)
content only
240px (200 + 20 × 2)
border-box
content + padding + border
200px; content is squeezed to 160px
Why does nearly every project switch to border-box globally? Because “when I say 200 wide I mean 200 wide” matches intuition. The default makes three columns at 33.3% wrap the moment you add padding — the wall every beginner hits.
Follow-up: “Is margin part of the box?” — even border-boxexcludes margin. Margin is always outside; it is the distance between boxes.
They will also ask about margin collapse: two adjacent block elements with margin-bottom: 20px and margin-top: 30pxgive you 30px, not 50px (the larger wins). This is why spacing so often ends up “slightly off”. Flex and grid children do not collapse.
CSS全局重置示意Illustrative
1/* 几乎每个项目开头都有这三行 */
2*,
3*::before,
4*::after{
5box-sizing:border-box;
6}
1/* Almost every project starts with these three lines */
会不会折叠。margin 会上下折叠,padding 永远不会。 想要「稳定的 20px 间距」用 padding 更可控。
负值。margin 可以是负数(常用来做重叠、抵消父级 padding), padding 不行。
会追问:「margin: 0 auto 为什么能居中,padding: auto 为什么不行?」—— margin 的 auto 会吃掉剩余空间并平分, padding 根本不支持 auto。 而且这招只对设了宽度的块级元素有效。
In one line: padding is inside the border — the gap between content and border; margin is outside — the gap between this box and everything else.
Three things decide which one you reach for:
Background and hit area. Padding belongs to the element, so the background paints over it and clicks on it count as clicks on the element; margin is empty space you cannot click. Always use padding to enlarge a button’s hit area.
Collapsing. Vertical margins collapse; padding never does. For a dependable 20px gap, padding is more predictable.
Negative values. Margin can be negative (used for overlaps, or to cancel a parent’s padding); padding cannot.
Follow-up: “Why does margin: 0 auto centre something when padding: auto does nothing?” —auto margins absorb the leftover space and split it evenly; padding does not support auto at all. And the trick only works on a block element with a set width.
In one line: Flex is one-dimensional (a row or a column, content-driven); Grid is two-dimensional (rows and columns together, layout-driven).
One sentence decides it: “Do I need to control alignment across rows and columns at once?” Yes → Grid. No → Flex.
Flex
Grid
Dimensions
One
Two
Who decides size
The content (items say how big they are)
The container (cells first, content after)
Typical use
Nav bars, button groups, image-plus-text inside a card, “text left, button right”
Page skeleton (header / sidebar / main / footer), product grids, calendars, label-column plus input-column forms
Weakness
After flex-wrap, rows know nothing about each other, so nothing lines up
You must plan the cells; restructuring is more work
Follow-up: “Can you use both?” — using both is the normal answer: Grid for the page skeleton, Flex for the contents of each cell. Saying “pick one” suggests you have not shipped much.
They will also ask what flex: 1 means: it is shorthand for flex-grow: 1; flex-shrink: 1; flex-basis: 0% — “I take the leftover space, I may be compressed, and my starting size counts as zero”. That is the shortest way to write “fixed sidebar plus fluid main area”.
CSS实际项目里的分工示意Illustrative
1/* Grid 搭骨架 */
2.layout{
3display:grid;
4grid-template-columns:240px1fr;/* 侧栏固定,主体吃剩下的 */
5grid-template-rows:56px1fr;
6min-height:100vh;
7}
8
9/* 格子内部用 Flex 排内容 */
10.topbar{
11display:flex;
12align-items:center;
13justify-content:space-between;
14gap:12px;
15}
16
17/* 「固定宽 + 自适应」的经典两行 */
18.sidebar{flex:00240px;}/* 不长不缩,就 240 */
19.content{flex:1;}/* 剩下全归我 */
1/* Grid for the skeleton */
2.layout{
3display:grid;
4grid-template-columns:240px1fr;/* sidebar fixed, main takes the rest */
5grid-template-rows:56px1fr;
6min-height:100vh;
7}
8
9/* Flex for the content inside a cell */
10.topbar{
11display:flex;
12align-items:center;
13justify-content:space-between;
14gap:12px;
15}
16
17/* The classic two lines for "fixed width plus fill the rest" */
18.sidebar{flex:00240px;}/* never grows, never shrinks, stays 240 */
19.content{flex:1;}/* takes everything that is left */
Pseudo-elements (invent an element):::before, ::after,::placeholder, ::selection
The real question is specificity. Compare three numbers — (id, class, type) — left to right, and one high digit beats ten thousand low ones:
Selector
(id, class, type)
div p
0, 0, 2
.card p
0, 1, 1
.card.on
0, 2, 0
#app p
1, 0, 1 ← beats all of the above
A pseudo-class counts as a class, a pseudo-element as a type, and :not() itself scores nothing but its argument does. Inline style outranks any selector, and !important outranks that — but do not treat !important as a solution; it usually means your selector design has already gone out of control.
What if they tie? The one written later wins. That is why loading your own CSS after a third-party stylesheet is often all you need.
In one line: traditionally three — an inline style attribute, an in-page <style> tag, an external file via <link> (plus@import from within CSS).
But what the interviewer wants is how it is done in a modern build:
Plain import — import "./styles.css"; the bundler takes over, styles are global.
CSS Modules — import s from "./x.module.css"; class names are hashed, so collisions are impossible by construction.
CSS-in-JS (styled-components, emotion) — styles live in JS, so props can drive them. The cost is runtime work.
Atomic (Tailwind) — you do not write CSS, you compose preset class names.
Follow-up: “Why is @import discouraged?” — because it is serial: the browser must download and parse the outer stylesheet before it even discovers the@import, then fetch again. That request chain delays first paint. @import handled by a build tool is merged at compile time and does not have this problem — pointing out that distinction is what earns the marks.
In one line: SCSS is one of Sass’s two syntaxes and a superset of CSS — valid CSS is valid SCSS — but it adds variables, nesting, mixins and functions, and compiles down to plain CSS.
Sass vs SCSS? Two syntaxes for the same tool:.sass is indentation-based with no braces or semicolons;.scss looks like CSS. .scss is what everyone uses now, because you can paste existing CSS straight in.
Four core abilities: variables ($brand: #2b6), nesting (hierarchy visible at a glance),@mixin / @include (reuse a group of declarations, with arguments), and @use for splitting files.
The follow-up this question really exists for: “Do you still need it?” — honestly, much less. Variables have been superseded by native CSS custom properties (--brand), and the native ones are strictly more capable: they live at runtime, JS can read and write them, and they follow theme switches (this site’s dark mode works exactly that way). Nesting has landed in the CSS standard too. What genuinely remains valuable is mixins and generated loops. Answering this way shows you know where the boundary is.
In one line: a preprocessor lets you write styles in a more capable language and compiles them to CSS. Sass, Less and Stylus all qualify.
Upsides: variables in one place, nesting that makes structure obvious, mixins for reuse, loops that generate families of rules (.mt-1 through .mt-10), and splitting into many small files that get merged.
Costs — this is the half they probe:
An extra build step. One more dependency, one more config, one more place things break.
Nesting is far too easy to over-use. Before you notice you have written .a .b .c .d span, specificity keeps climbing, and the only way out is !important. This is the preprocessor’s most real trap — in practice teams cap themselves at about three levels.
Debugging needs source maps. DevTools shows you the compiled output and the line numbers do not match.
Onboarding cost. Newcomers must learn extra syntax.
How to land the conclusion: “Worth it on large projects with a design system and lots of generated styles; for small projects plain CSS plus custom properties is enough, because the two problems it originally solved — variables and nesting — are now native.” A weighed answer beats unconditional praise.
In one line: one codebase that lays out sensibly at any screen size — rather than building a separate mobile site.
Four techniques, most important first:
The viewport meta tag — the precondition; without it nothing else matters (see #381).
Flexible units — widths in % /fr / min() / clamp(), font sizes in rem; stop hard-coding px everywhere. clamp(16px, 4vw, 24px) gives you a fluid font size with hard limits in a single line.
Media queries — @media (max-width: 768px) to change layout.
Flexible layout — flex-wrap and grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)) often adapt without a single media query.
Follow-up: “How do you choose breakpoints?” — the right answer is “from the content, not from device sizes”: drag the window narrower and add a breakpoint wherever it starts looking wrong. Chasing a list of iPhone dimensions is outdated, because device sizes change every year.
They will also ask about mobile-first: write the narrow layout as the default and add to it with min-width. Mobile then downloads the least CSS, and “adding” is easier to reason about than “undoing” — overriding downwards with max-width usually means repeatedly resetting properties.
99 道来自面试题库 #269–#387;TypeScript 深度那 6 道是 DrillLab 自出的(senior 补强,卡片上有标注)。答案都是 DrillLab 写的,所以讲解里的代码块一律标「示意」。每道题都能点回它出处的那一节课。99 questions come from the interview bank (#269–#387); the 6 TypeScript deep-dive ones are DrillLab-made (marked on the card). All answers are written by DrillLab, so every code block here is labelled “demo”. Each card links back to the lesson it came from.