阅读视图

发现新文章,点击刷新页面。

CSS-深度解析 Position 五大定位模式

前言

在 CSS 布局中,position 属性是控制元素“脱离常规”的关键。无论是想要悬浮的导航栏,还是精准重叠的图层,都离不开对定位属性的深入理解。本文将带你搞懂 relativeabsolutefixedsticky 的底层逻辑。

一、 Position 核心参数详解

属性值 含义 布局表现 参考物
static 默认值 正常文档流布局。 无(Top/Left 等属性无效)。
relative 相对定位 不脱离文档流,占据原始空间。 元素在文档流中的原始位置
absolute 绝对定位 完全脱离文档流,不占位。 最近的 非 static 祖先元素。
fixed 固定定位 完全脱离文档流,不占位。 浏览器窗口 (Viewport)
sticky 粘性定位 混合模式,特定条件下生效。 最近的滚动祖先元素

二、 偏移属性:Left、Right、Top、Bottom

1. 生效前提

这些偏移属性仅在 position 不为 static 时生效。它们定义了元素边缘相对于参考物的距离。

2. 不同定位下的偏移逻辑

  • Relative (相对自身)

    设置 left: 20px,元素会相对于它原本在文档流中的位置向右移动 20px。它原来的位置依然被保留,不会被后续元素顶替。

  • Absolute (相对祖先)

    设置 left: 0,元素会紧贴最近的已定位(非 static)祖先元素的左内边缘。

  • Fixed (相对窗口)

    设置 right: 10px; bottom: 10px;,元素将永久停留在浏览器窗口的右下角,不随页面滚动而移动。


三、 现代布局黑科技:Sticky (粘性定位)

  • 表现:它是 relativefixed 的结合体。

  • 示例top: 0; position: sticky;

    当页面未滚动到该元素时,它是 relative(随内容滚动);当元素滚动到视口顶部时,它会像 fixed 一样“粘”在顶部,直到其父容器消失在视口中。

  • 常用场景:表格标题行固定、侧边栏跟随。


四、 核心面试考点:Absolute 的参考物

误区修正:很多人认为绝对定位是相对于“父元素”。

准确定义:是相对于最近的、非 static 定位的祖先元素。如果向上找遍了所有祖先元素都没有定位,则相对于 初始包含块(通常是 <html> 定位。


五、 总结与最佳实践

  1. 子绝父相:这是最经典的用法。父元素设为 relative(仅为了提供参考坐标),子元素设为 absolute 实现精准定位。
  2. 避免滥用 Fixed:固定定位会脱离文档流,过多的固定元素会遮挡用户视线,且在移动端可能存在兼容性坑位。
  3. 层级管理:配合 z-index 使用,数值越大,图层越靠上(仅在已定位元素上生效)。

CSS-布局基石:深度解析四大定位方式与文档流机制

前言

在 CSS 的世界里,页面布局的本质就是控制元素在“流”中的位置。理解普通流、浮动、绝对定位与固定定位,是掌握复杂页面结构的钥匙。本文将带你理清它们的底层逻辑与相互影响。

一、 普通流 (Normal Flow)

普通流(也叫文档流)是页面最默认的布局方式。

  • 布局逻辑:元素按照其在 HTML 中出现的先后顺序,自上而下、自左而右排列。

  • 元素表现

    • 块级元素 (Block) :独占一行,垂直排列。
    • 行内元素 (Inline) :水平排列,遇到边缘自动换行。
  • 地位:它是所有布局的基础,除非显式更改,否则元素都在流中。


二、 浮动 (Float)

浮动最初是为了实现“文字环绕图片”的效果,但后来演变成了主流的列布局工具。

  • 布局逻辑:元素首先处于普通流位置,然后向左或向右偏移,直到碰到包含框或另一个浮动元素的边缘。
  • 脱离文档流:浮动元素会部分脱离文档流。它不再占据普通流的空间,但依然会影响文档流中文字的排列(形成环绕)。
  • 注意:使用浮动后务必记得清除浮动 (Clearfix) ,否则会导致父元素高度坍塌。

三、 绝对定位 (Absolute Positioning)

绝对定位让元素拥有了“自由移动”的能力。

  • 布局逻辑:元素完全脱离文档流,不再占据物理空间,兄弟元素会像它不存在一样向上位移。

  • 定位参考(包含块)

    • 相对于其最近的非 static 定位的祖先元素进行定位。
    • 如果找不到,则相对于初始包含块(通常是 <html>)定位。
  • 常用技巧:父级 relative,子级 absolute


四、 固定定位 (Fixed Positioning)

固定定位是特殊的绝对定位,它让元素在屏幕上“静止”。

  • 布局逻辑:元素完全脱离文档流
  • 定位参考:相对于浏览器视口 (Viewport) 进行定位。
  • 特点:无论页面如何滚动,元素始终保持在屏幕的固定位置。常用于导航栏、回到顶部按钮或侧边广告。

五、 核心对比:脱离文档流情况

这是面试中最常被问到的对比点:

布局方式 是否脱离文档流 占据空间 相对参考物
普通流 兄弟元素与父元素
浮动 部分脱离 否(仅对文本有影响) 父元素边缘
绝对定位 完全脱离 最近的非 static 祖先元素
固定定位 完全脱离 浏览器视口

💡 总结建议

  • 普通流是常态;
  • 浮动处理简单的横向排列(虽然现代开发更多使用 Flex);
  • 绝对定位处理元素重叠和局部精准定位;
  • 固定定位处理与窗口挂钩的悬浮组件。

CSS-玩转背景控制与文字排版艺术

前言

在前端开发中,细节决定质感。如何让背景图只在内容区域显示?如何优雅地处理文字溢出?本文将带你深入探索 CSS 中关于 backgroundText 的进阶属性,让你的页面更加精致。

一、 背景属性的高级控制

1. background-clip(背景裁剪)

决定背景延伸到什么位置

  • border-box (默认):背景延伸至边框外沿(但在边框下层)。
  • padding-box:背景延伸至内边距外沿,不会显示在边框下。
  • content-box:背景只在内容区域显示。
  • text (特殊):将背景裁剪为文字的前景色(常用于制作渐变文字)。

2. background-origin(背景原点)

决定背景图片的绘制起点(即 background-position: 0 0 的位置)。

  • padding-box (默认):图片左上角对齐 padding 边缘。
  • border-box:图片左上角对齐 border 边缘。
  • content-box:图片左上角对齐内容区域边缘。

3. background-size(背景尺寸)

  • contain:保持比例缩放,确保图片完整显示在容器内(可能会有留白)。
  • cover:保持比例缩放,确保图片完全覆盖容器(可能会被裁剪)。
  • 具体数值:如 100px 50%,手动指定宽高。

4. box-decoration-break(元素断裂处的修饰)

当元素被分为几个独立的盒子(如使内联元素span跨越多行),background-break属性用来控制背景怎样在这些不同的盒子中显示,取值如下:

  • slice (默认):背景像是在一个整体上绘制后被切开,断裂处没有边框/内边距。
  • clone:每个断裂的盒子都拥有独立的背景、边框和内边距。

二、 文字排版与换行控制

1. 换行与溢出

  • word-wrap / overflow-wrap

    • normal:浏览器默认。
    • break-word:如果单词太长无法在一行显示,允许在单词内换行(更常用)。
  • word-break: break-all:强制在单词内任何字符间断行,适合处理超长连续字符。

2. text-overflow(文本溢出处理)

常用于处理单行文本超出容器:

  • clip:简单裁剪,不显示省略号。
  • ellipsis:显示省略号 ...(需配合 overflow: hiddenwhite-space: nowrap 使用)。

三、 text-decoration:文字装饰的简写艺术

现代 CSS 支持更精细的文字装饰控制: text-decoration: <line> <color> <style>

1. 线型 (Line)

  • none:去除装饰(最常用于 <a> 标签)。
  • underline:下划线。
  • overline:上划线。
  • line-through:删除线。

2. 样式 (Style)

  • solid:实线(默认)。
  • double:双线。
  • dotted:点线。
  • dashed:虚线。
  • wavy波浪线

四、 实战 tips:渐变文字效果

利用 background-clip: text,你可以轻松实现绚丽的渐变文字:

.gradient-text {
  background: linear-gradient(to right, red, blue);
  -webkit-background-clip: text; /* 必须加前缀 */
  color: transparent;           /* 文字设为透明,露出背景 */
  font-size: 40px;
}

CSS-彻底搞懂选择器优先级与CSS单位

前言

为什么我写的样式不生效?为什么那个单位在移动端会缩放?理解 CSS 的优先级(Specificity)和度量单位,是每一个前端开发者从“画页面”走向“精通布局”的必经之路。

一、 CSS 优先级(权重)全解析

CSS 样式的应用遵循“就近原则”和“权重计算原则”。

1. 权重等级排列

我们将不同选择器划分为不同的等级:

  1. !important:无视规则,权重最高。
  2. 行内样式 (Inline style) :写在标签 style 属性里的样式。
  3. ID 选择器:如 #header
  4. 类、伪类、属性选择器:如 .content:hover[type="text"]
  5. 元素(标签)、伪元素选择器:如 div::before
  6. 通用选择器 (*) 、子选择器 (> )、相邻选择器 (+):权重极低(通常计为 0)。
  7. 继承的样式:权重最低。

2. 权重计算法(三位计数法)

为了方便对比,我们可以给它们分配分值(非绝对数值,仅作逻辑参考):

  • ID 选择器:100
  • 类/属性/伪类:10
  • 标签/伪元素:1

规则:从左往右比较,数值大的获胜。如果数值相等,则后者覆盖前者

⚠️ 注意!important 是“核武器”,如果它用于简写属性(如 background: !important),则其包含的所有子属性(color, image 等)都会获得最高权重,应谨慎使用


二、 CSS 常用度量单位

根据参考参照物的不同,单位可分为以下几类:

1. 绝对单位

  • px (像素) :最常用的基本单位,物理像素点,不随环境改变。

2. 相对单位(基于字体)

  • em:相对于当前元素font-size

    • 注意:如果当前元素未设置,则参考父元素;如果整个页面都没设置,则参考浏览器默认值(16px)。
  • rem (Root em) :相对于根元素 (<html>)font-size。是移动端适配的首选。

3. 相对单位(基于视口)

  • vw / vh:相对于浏览器可视窗口的宽度/高度。1vw 等于视口宽度的 1%。
  • % (百分比) :通常相对于父元素的对应属性(宽度、高度等)。

三、 现代布局黑科技

1. calc() 计算属性

允许在声明 CSS 属性值时执行加减乘除运算。

  • 语法width: calc(100% - 20px);
  • 注意:运算符前后必须保留空格。

2. aspect-ratio 设置宽高比

过去我们需要用 padding-top 技巧来实现等比缩放,现在一行代码搞定:

.box {
  width: 500px;
  aspect-ratio: 16 / 9; /*这时的宽高比就为16比9*/
  background: lightblue;
}

四、 总结:优先级冲突时的排查思路

  1. !important:有没有被强行置顶。
  2. 算权重值:ID > 类 > 标签。
  3. 看顺序:权重相同时,写在后面的样式生效。
  4. 看距离:行内样式 > 内部/外部样式表。
  5. 看加载:内部样式和外联样式的优先级,取决于它们在 HTML 中出现的先后顺序。

CSS-深度解析伪类与伪元素

前言

在 CSS 的世界里,单冒号 : 和双冒号 :: 并不是随心所欲使用的。它们分别代表了伪类伪元素。理解它们的区别,不仅能帮你写出更优雅的选择器,还能在面试中展示扎实的基础。

一、 核心区别:它们到底是什么?

  • 伪类 (Pseudo-classes)

    • 本质:代表一种状态
    • 作用:当元素处于某种特定状态时(如鼠标悬停、获得焦点、被选中),为其添加样式。它选择的是已存在的元素
    • 语法:使用单冒号 :(如 :hover)。
  • 伪元素 (Pseudo-elements)

    • 本质:代表一种虚拟内容
    • 作用:创建一个不在 DOM 树中的“虚拟元素”。例如,为一个段落的开头添加一个字母,或者在元素前后插入修饰性的内容。
    • 语法:CSS3 规范建议使用双冒号 ::(如 ::after),以区分伪类。

二、 常用伪类:状态与结构选择

伪类可以分为行为伪类结构伪类表单伪类

1. 行为与状态伪类

选择器 含义
E:link 匹配未访问的链接
E:visited 匹配已访问的链接
E:hover 鼠标悬停在元素上
E:active 鼠标按下尚未释放(激活状态)
E:focus 元素获得焦点(如输入框点击后)

2. 结构伪类

选择器 含义
E:first-child 匹配父元素的第一个子元素,且该子元素必须是 E
E:last-child 匹配父元素的最后一个子元素,且该子元素必须是 E
E:nth-child(n) 匹配父元素中第 n 个子元素(n 可以是数字、关键字或公式)
E:first-of-type 匹配同类型兄弟元素中的第一个 E
E:only-child 匹配父元素中唯一的子元素

3. 表单相关伪类

选择器 含义
E:enabled 匹配可用的表单元素
E:disabled 匹配被禁用的表单元素
E:checked 匹配单选框或复选框被选中的状态

三、 常用伪元素:内容与样式扩展

伪元素在 CSS3 规范中统一使用双冒号 ::

选择器 含义 场景
::before 在 E 元素内容的最前面插入内容 字体图标、修饰性装饰
::after 在 E 元素内容的最后面插入内容 清除浮动、对话框小箭头
::first-line 匹配 E 元素的第一行文字 杂志风格的排版
::first-letter 匹配 E 元素的第一个字母 首字下沉效果
::selection 匹配用户在页面上选中的文本 自定义选中文本的颜色

四、 深度辨析:nth-child vs nth-of-type

这是面试中最常被问到的细节:

  • p:nth-child(2) :选择父元素的第二个子元素,如果这个子元素是 <p>,则应用样式。如果第二个子元素是 <div>,则选择失败。
  • p:nth-of-type(2) :选择父元素下第二个 <p> 类型的子元素,不考虑非 <p> 标签。

💡 总结

  • 伪类是用来增强选择器的,描述的是状态(如被点击、被移动)。
  • 伪元素是用来创建新内容的,虽然在 HTML 里看不到,但在 CSS 中可以操作。
  • 写代码时,尽量遵循 CSS3 规范:状态用单冒号,内容用双冒号

DOM-深度掌握 HTMLElement:从基础操作到高性能交互

前言

在 DOM 树中,Element 类型是我们交互最频繁的节点。无论是修改样式、监听焦点,还是动态插入内容,都离不开它。本文将带你系统复习 Element 的核心 API,并揭示一些在实际开发中容易忽略的细节与陷阱。

一、 Element 节点基础

Element 表示 HTML 中的元素节点。通过 document.createElement() 可以动态创建。

  • nodeType: 1
  • nodeName: 返回大写标签名(如 "DIV")。
  • nodeValue: 始终为 null

1. 标准属性

可以直接通过点语法(.)访问的常见属性:idtitlelangdir语言的书写方向("ltr"表示从左到右,"rtl"表示从右到左)。

  • className: 对应 HTML 的 class 属性。由于 class 是 JS 关键字,故属性名做了转换。

2. 自定义属性:dataset

HTML5 规范了 data- 前缀的自定义属性,通过 dataset 对象可以优雅地读写。

<div id="myDiv" data-app-id="12345"></div>

const div = document.getElementById("myDiv");

// 获取:注意 camelCase 转换(data-app-id -> appId)
console.log(div.dataset.appId); 

// 设置
div.dataset.userName = "Nicholas"; // 自动变为 data-user-name="Nicholas"

二、 属性操作:Attribute vs Property

这是最容易混淆的地方:getAttribute 操作的是 HTML 文档中的特性,而直接赋值操作的是 JS 对象的属性

方法 描述 特点
getAttribute(name) 获取 HTML 特性 始终返回字符串;获取类名需传 "class"
setAttribute(name, v) 设置 HTML 特性 会同步到 HTML 结构中
removeAttribute(name) 彻底删除特性 不仅仅是清空值

💡 建议: 对于 idclassName 等标准属性,直接使用点语法性能更好;对于非标准的自定义属性,使用 dataset


三、 内容操控:安全与性能

1. innerHTML vs textContent

  • innerHTML: 读写 HTML,会解析标签。注意: 存在 XSS 攻击风险。
  • textContent: 读写纯文本。性能更好且更安全。

2. 高性能插入:insertAdjacentHTML

  • 语法:insertAdjacentText(first,sencond)
    • second:插入内容
    • first:要插入的位置
      • beforebegin:插入当前元素前面,作为前一个同胞节点
      • afterbegin:插入当前元素内部,作为新的子节点或放在第一个子节点前面
      • beforeend:插入当前元素内部,作为新的子节点或放在最后一个子节点后面
      • afterend:插入当前元素后面,作为下一个同胞节点

相比于 innerHTML += '...'(会导致整个子树重新渲染),insertAdjacentHTML 可以将字符串解析为 DOM 并精确插入,性能极高。

// 语法:element.insertAdjacentHTML(position, html)
element.insertAdjacentHTML("afterbegin", "<span>New Content</span>");

四、 类名管理:classList API

以前我们需要手动操作 className 字符串,现在有了 classList 这个神器。

  • add(value) : 添加类名。
  • remove(value) : 删除类名。
  • contains(value) : 判断是否存在。
  • toggle(value) : 切换(有则删,无则加)。

五、 几何尺寸:彻底搞懂各种 Height/Width

在处理滚动和布局时,这些属性非常关键。

属性 包含范围
clientWidth / clientHeight 内容 + 内边距 (Padding)
offsetWidth / offsetHeight 内容 + 内边距 + 边框 (Border)
scrollWidth / scrollHeight 包含滚动条滚出的隐藏部分的完整尺寸

进阶:获取精确位置

getBoundingClientRect() 返回元素相对于浏览器视口top, left, right, bottom, width, height


六、 焦点管理

  • document.activeElement: 指向当前获得焦点的元素(如正处在输入状态的 input)。
  • element.focus() : 强制让元素获得焦点。
let button = document.getElementById("myButton");
button.focus();
console.log(document.activeElement === button); // true 

七、 面试模拟题

Q1:isSameNode()isEqualNode() 有什么区别?

参考回答:

  • isSameNode() (等同于 ===): 检查两个变量是否引用同一个 DOM 实例。
  • isEqualNode(): 检查两个节点是否长得一样(类型相同、属性相同、子节点结构也相同)。

Q2:为什么通过 innerHTML 插入的 <script> 不会执行?

参考回答:

这是浏览器的安全策略。如果需要执行脚本,必须通过 document.createElement('script') 手动创建并插入到文档中。

❌