CSS
选择器
优先级计算
权重体系(四位数值,从左到右权重递减):
!important → 无限大(打破级联规则)
内联样式 style="" → 1,0,0,0
ID 选择器 (#id) → 0,1,0,0
类/属性/伪类 → 0,0,1,0
元素/伪元素 → 0,0,0,1
通配符/组合器 → 0,0,0,0
继承样式 → 无权重
/* 权重示例 */
#nav .item a:hover {} /* 0,1,2,1 */
body #content .post {} /* 0,1,1,1 */
li.active {} /* 0,0,1,1 */
ul li {} /* 0,0,0,2 */
!important 处理规则:
- 多个
!important按权重比较 - 只能在 custom property 降级或覆盖第三方样式时使用
- 正常项目中应避免,它破坏级联,让覆盖变得困难
CSS 选择器性能(从右向左匹配)
浏览器解析选择器时从右向左匹配(RLT, Right-to-Left):
/* 浏览器先找到所有 a 元素,再向上过滤是否在 .nav 内 */
.nav a {}
/* 比下面更快(因为先筛掉大量非 .highlight 元素) */
div.highlight {}
性能排序(从快到慢):
#id> 通过 id 直接定位.class> 通过类名快速过滤tag> 遍历所有元素[attr]> 属性匹配- 伪类/伪元素 > 需额外计算
实际意义:在多数应用中,选择器性能差异可忽略(除非有上万元素),优先选择语义清晰的写法。
伪类与伪元素
| 类型 | 语法 | 作用 | 示例 |
|---|---|---|---|
| 伪类 | : |
元素特定状态 | :hover, :focus, :nth-child(2n) |
| 伪元素 | :: |
元素的特定部分 | ::before, ::after, ::first-line |
关键伪类:
/* 结构伪类 */
:first-child / :last-child
:nth-child(2n+1) /* 奇数项 */
:nth-child(-n+3) /* 前 3 项 */
:nth-last-child(1) /* 倒数第 1 项 */
:first-of-type / :last-of-type
:only-child
/* 状态伪类 */
:enabled / :disabled
:checked
:valid / :invalid
:required / :optional
:focus-visible /* 键盘聚焦时(推荐替代 :focus) */
:focus-within /* 自身或后代聚焦 */
:empty /* 无子节点(含文本节点则不为空) */
:not(selector) /* 否定(可传多个选择器 :not(.a, .b)) */
:is(selector) /* 匹配任一(比逗号选择器权重更低 :is(h1, h2, h3)) */
:where(selector) /* 同 :is,但权重始终为 0 */
伪元素:
/* ::before / ::after 必须有 content */
.element::before {
content: '';
display: block;
/* 用于图标、装饰、清除浮动 */
}
.element::after {
content: attr(data-tip); /* 动态属性值 */
}
/* ::first-letter / ::first-line —— 排版用 */
p::first-letter { font-size: 2em; float: left; }
p::first-line { font-weight: bold; }
/* ::selection —— 选中文本样式 */
::selection { background: #b3d4fc; color: #000; }
/* ::placeholder —— 输入框占位文字 */
input::placeholder { color: #999; }
盒模型
content-box vs border-box
/* 默认值:width 只包含内容区 */
box-sizing: content-box;
/* width = content,实际占宽 = content + padding + border */
/* 推荐:width 包含内容+内边距+边框 */
box-sizing: border-box;
/* width = content + padding + border */
对比:
/* content-box */
.element {
width: 200px;
padding: 20px;
border: 2px solid;
/* 实际宽度 = 200 + 20*2 + 2*2 = 244px */
}
/* border-box */
.element {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 2px solid;
/* 实际宽度 = 200px,内容宽度 = 200 - 40 - 4 = 156px */
}
全局设置(推荐):
*,
*::before,
*::after {
box-sizing: border-box;
}
margin 塌陷
规则:垂直相邻的块级元素 margin 取最大值,不叠加。
<div style="margin-bottom: 30px;">A</div>
<div style="margin-top: 20px;">B</div>
<!-- A 和 B 之间的间距 = 30px,不是 50px -->
父子塌陷:父元素没有 border/padding/inline-content/overflow:hidden/BFC 时,子元素的 margin-top 会穿透到父元素外部。
解决:
- 父元素设置
overflow: hidden(触发 BFC) - 父元素设置
padding: 1px或border: 1px solid transparent - 使用
display: flow-root(最干净的方式)
BFC(Block Formatting Context)
触发条件(任一):
overflow非visible(hidden/auto/scroll)display: flow-root(最语义化)display: inline-block / table-cell / flex / gridfloat非noneposition: absolute / fixed
/* 创建 BFC 的推荐方式 */
.container {
display: flow-root; /* 2021+ 所有现代浏览器支持 */
}
应用场景:
- 清除浮动:父容器创建 BFC 包含浮动子元素
- 防止 margin 塌陷:父元素创建 BFC 隔离内外 margin
- 两栏自适应布局:
overflow: hidden触发 BFC 避免浮动覆盖
/* BFC 两栏自适应布局 */
.floated {
float: left;
width: 200px;
}
.main {
overflow: hidden; /* 触发 BFC,不与浮动重叠 */
}
布局体系
正常流(Normal Flow)
块级元素垂直排列(display: block),行内元素水平排列(display: inline)。
/* display 常见值 */
block /* 块级,独占一行 */
inline /* 行内,宽高无效,水平排列 */
inline-block /* 行内但可设宽高 */
none /* 隐藏(不占空间,与 visibility: hidden 不同) */
Flexbox
容器属性:
.flex-container {
display: flex;
/* 或 display: inline-flex; */
/* 主轴方向 */
flex-direction: row | row-reverse | column | column-reverse;
/* 换行 */
flex-wrap: nowrap | wrap | wrap-reverse;
/* 主轴对齐 */
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
/* 交叉轴对齐(单行) */
align-items: stretch | flex-start | flex-end | center | baseline;
/* 交叉轴对齐(多行) */
align-content: stretch | flex-start | flex-end | center | space-between | space-around;
/* gap 间距 */
gap: 16px; /* 行和列 */
row-gap: 16px;
column-gap: 12px;
}
子项属性:
.flex-item {
/* 增长比例(默认为 0,即不增长) */
flex-grow: 1;
/* 收缩比例(默认为 1) */
flex-shrink: 1;
/* 初始大小(默认为 auto,即内容大小) */
flex-basis: auto | 200px | 50%;
/* 简写:flex: grow shrink basis */
flex: 1; /* 1 1 0% */
flex: auto; /* 1 1 auto */
flex: none; /* 0 0 auto */
flex: 0 0 200px; /* 固定 200px */
/* 覆盖容器 align-items */
align-self: auto | stretch | center | flex-end;
/* 顺序(默认为 0,值越小越靠前) */
order: 1;
}
经典布局示例:
/* 圣杯布局:中间自适应,两侧固定 */
.layout {
display: flex;
min-height: 100vh;
}
.sidebar {
flex: 0 0 250px;
}
.main {
flex: 1;
}
/* 等分布局 */
.row {
display: flex;
gap: 16px;
}
.col {
flex: 1; /* 每项等宽 */
}
/* 垂直居中 */
.center {
display: flex;
justify-content: center;
align-items: center;
}
/* 粘性 footer */
.page { display: flex; flex-direction: column; min-height: 100vh; }
.content { flex: 1; }
footer { flex-shrink: 0; }
Grid
容器属性:
.grid {
display: grid;
/* 列定义 */
grid-template-columns: 200px 1fr 2fr; /* 三列:固定+比例 */
grid-template-columns: repeat(3, 1fr); /* 三等分布局 */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* 响应式列 */
grid-template-columns: 200px auto 200px; /* 中间自适应 */
/* 行定义 */
grid-template-rows: 100px auto 80px;
/* 区域命名 */
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
/* 间距 */
gap: 16px;
row-gap: 16px;
column-gap: 16px;
/* 隐式网格行高 */
grid-auto-rows: minmax(100px, auto);
/* 对齐方式 */
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
place-items: center center; /* justify-items align-items 简写 */
justify-content: start | end | center | stretch | space-between | space-around | space-evenly;
align-content: start | end | center | stretch | space-between | space-around | space-evenly;
}
子项属性:
.grid-item {
/* 单元格跨列 */
grid-column: 1 / 3; /* 从列线 1 到列线 3 */
grid-column: 1 / span 2; /* 跨 2 列 */
grid-column: 1 / -1; /* 从第一列到最后一列 */
/* 单元格跨行 */
grid-row: 1 / 3;
/* 简写 */
grid-area: header; /* 对应 grid-template-areas 命名 */
grid-area: 1 / 1 / 3 / 4; /* row-start / col-start / row-end / col-end */
/* 单个单元格内对齐 */
justify-self: start;
align-self: end;
place-self: center;
}
fr 单位:fr 是 Grid 的弹性单位,表示剩余空间的比例分配。只在 Grid 布局中有效。
/* 第一列固定 200px,剩余空间第二列占 1/3,第三列占 2/3 */
grid-template-columns: 200px 1fr 2fr;
Grid vs Flexbox 选择:
| 场景 | 推荐 |
|---|---|
| 一维布局(行或列) | Flexbox |
| 二维布局(行列同时控制) | Grid |
| 内容驱动大小 | Flexbox |
| 布局驱动大小 | Grid |
| 等分布局 | Grid (repeat) |
| 对齐与分布 | 两者均可 |
定位
/* static —— 默认,正常流 */
position: static;
/* relative —— 相对自身原本位置偏移,不脱离文档流 */
position: relative;
top: 10px; left: 20px; /* 原本位置占据空间,视觉偏移 */
/* absolute —— 脱离文档流,相对于最近的 non-static 定位祖先 */
position: absolute;
top: 0; right: 0; /* 相对于父定位 */
/* fixed —— 脱离文档流,相对于视口 */
position: fixed;
bottom: 0; /* 粘性底部操作栏 */
/* sticky —— 相对与 fixed 混合(兼容性需注意) */
position: sticky;
top: 0; /* 滚动到顶部后粘住 */
/* 条件:必须有 top/bottom/left/right 之一 */
/* 生效需父容器未 overflow: hidden */
sticky 常见场景:
/* 粘性导航:滚动到顶部后固定 */
.nav {
position: sticky;
top: 0;
z-index: 100;
background: white;
}
/* sticky 失效排查 */
/* 1. 父元素有 overflow: hidden/scroll/auto */
/* 2. 未设置 top/bottom/left/right */
/* 3. 父元素高度小于 sticky 元素本身 */
多列布局
.multi-column {
column-count: 3; /* 固定列数 */
column-width: 300px; /* 最小列宽(与 column-count 结合) */
columns: 300px 3; /* 简写:宽度 数量 */
column-gap: 2em;
column-rule: 1px solid #ccc; /* 列分割线 */
column-span: all; /* 标题跨列 */
}
响应式设计
媒体查询
/* 移动优先(推荐)—— 基础样式为手机,然后增强 */
/* 基础样式:手机 */
body { font-size: 14px; }
/* >= 768px 平板 */
@media (min-width: 768px) {
body { font-size: 16px; }
.sidebar { display: block; }
}
/* >= 1024px 桌面 */
@media (min-width: 1024px) {
.layout { display: grid; grid-template-columns: 250px 1fr; }
}
/* 桌面优先 —— 基础样式为桌面,然后降级 */
body { font-size: 18px; }
@media (max-width: 767px) {
body { font-size: 14px; }
}
/* 更多查询条件 */
@media (prefers-color-scheme: dark) { /* 暗色模式 */}
@media (prefers-reduced-motion: reduce) { /* 减少动画 */}
@media (hover: hover) { /* 支持悬停设备 */}
@media (pointer: coarse) { /* 触摸设备 */}
@media (orientation: portrait) { /* 竖屏 */}
rem vs em vs vw/vh
/* em —— 相对于父元素字体大小(容易嵌套失控) */
.parent { font-size: 20px; }
.child { font-size: 1.5em; } /* 30px */
.grandchild { font-size: 0.8em; } /* 24px(相对于 30px) */
/* rem —— 相对于根元素(html)字体大小(推荐) */
html { font-size: 16px; }
h1 { font-size: 2rem; } /* 32px */
p { font-size: 1rem; } /* 16px */
/* vw/vh —— 相对于视口 */
.fullscreen { height: 100vh; } /* 全屏高度 */
.fullwidth { width: 100vw; } /* 全宽 */
.hero { height: 50vh; } /* 半屏 */
.sidebar { width: 20vw; }
/* 注意:100vw 包含滚动条宽度,可能导致水平溢出 */
/* dvh/svh/lvh —— 动态视口单位(解决移动端地址栏问题) */
.hero { height: 100dvh; } /* 动态视口高度 */
clamp / min / max
/* clamp(MIN, PREFERRED, MAX) —— 流体排版核心 */
h1 {
font-size: clamp(1.5rem, 3vw + 1rem, 3rem);
/* 最小 1.5rem,首选 3vw+1rem,最大 3rem */
}
/* min() / max() */
.sidebar {
width: min(300px, 30%); /* 取两者中较小值 */
}
.card {
width: max(250px, 50%); /* 取两者中较大值 */
}
容器查询(@container)
/* 定义容器 */
.card-container {
container-type: inline-size; /* 基于内联轴尺寸 */
container-name: card; /* 可选命名 */
}
/* 容器查询(类似媒体查询但基于容器尺寸) */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
}
}
@container (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}
动画
transition
.element {
/* property duration timing-function delay */
transition: transform 0.3s ease-in-out, opacity 0.3s;
/* 简写全部 */
transition: all 0.3s ease;
/* 分写 */
transition-property: transform, opacity;
transition-duration: 0.3s, 0.2s;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-delay: 0s, 0.1s;
/* 限制可过渡的属性:最好指定属性,避免 all */
/* 仅对 opacity 和 transform 可过渡(GPU 加速友好) */
}
.element:hover {
transform: scale(1.1);
opacity: 0.8;
}
贝塞尔曲线:
/* 内置 */
ease /* cubic-bezier(0.25, 0.1, 0.25, 1) */
linear /* cubic-bezier(0, 0, 1, 1) */
ease-in /* cubic-bezier(0.42, 0, 1, 1) */
ease-out /* cubic-bezier(0, 0, 0.58, 1) */
ease-in-out /* cubic-bezier(0.42, 0, 0.58, 1) */
/* 自定义 */
.custom {
transition: transform 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55);
/* 弹性效果:超出目标一点后回弹 */
}
animation / @keyframes
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(-100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
.element {
/* name duration timing-function delay iteration-count direction fill-mode play-state */
animation: slideIn 0.3s ease-out 0s 1 normal both;
/* 分写 */
animation-name: slideIn;
animation-duration: 0.3s;
animation-timing-function: ease-out;
animation-delay: 0s;
animation-iteration-count: infinite; /* 无限循环 */
animation-direction: alternate; /* 交替方向 */
animation-fill-mode: both; /* 开始前/结束后保持首尾状态 */
animation-play-state: paused; /* 控制暂停/运行 */
}
transform
/* 2D 变换 */
transform: translateX(100px); /* 水平移动 */
transform: translateY(-50%); /* 垂直移动(百分比相对于自身尺寸) */
transform: translate(100px, -50%);
transform: scale(1.5); /* 缩放 */
transform: scaleX(1.2);
transform: rotate(45deg);
transform: rotate(0.5turn); /* 半圈 */
transform: skew(10deg, 5deg); /* 倾斜 */
/* 3D 变换 */
transform: perspective(1000px) rotateY(45deg);
transform: translate3d(0, 0, 100px);
transform: rotateX(60deg);
/* transform-origin */
transform-origin: center; /* 默认 */
transform-origin: top left;
transform-origin: 50% 100%;
/* 多个变换组合(顺序影响结果) */
transform: translateX(100px) rotate(45deg) scale(1.5);
will-change
/* 告知浏览器哪些属性会变化,让浏览器提前优化 */
.element {
will-change: transform, opacity;
}
/*
* 注意事项:
* - 不要给大量元素设置
* - 在变化前设置,变化后移除
* - 过度使用会浪费内存
*/
GPU 加速与合成层
触发 GPU 合成的 CSS 属性:
transform: translateZ(0)或translate3d(0,0,0)—— 强制提升为合成层will-change: transform / opacityopacityfilter<video>/<canvas>/<iframe>
动画性能属性对比:
| 属性 | 触发操作 | 性能 |
|---|---|---|
transform |
合成 | 最佳(仅合成线程) |
opacity |
合成 | 最佳 |
left/top |
布局+绘制+合成 | 差(触发回流) |
width/height |
布局+绘制+合成 | 差 |
color/background |
绘制+合成 | 中等 |
box-shadow |
绘制+合成 | 中等 |
合成层创建条件(硬件加速):
/* 强制合成 */
.optimized {
transform: translateZ(0);
/* 或 */
will-change: transform;
}
FLIP 动画技巧
FLIP(First, Last, Invert, Play)—— 高性能动画技术,避免计算真实变化量。
function flipAnimation(el, callback) {
// First:记录初始位置
const first = el.getBoundingClientRect();
// 执行变化
callback();
// Last:记录最终位置
const last = el.getBoundingClientRect();
// Invert:计算差异并反向设置
const dx = first.left - last.left;
const dy = first.top - last.top;
const dw = first.width / last.width;
const dh = first.height / last.height;
el.style.transform = `translate(${dx}px, ${dy}px) scale(${dw}, ${dh})`;
el.style.transition = 'none';
// Play:触发动画回到最终状态
requestAnimationFrame(() => {
el.style.transition = 'transform 0.3s ease';
el.style.transform = '';
});
}
FLIP 核心:不计算中间状态,只做"记录-反向-播放"三步,动画性能极高。
CSS 工程化
CSS 模块化方案
BEM(Block Element Modifier):
/* Block:独立组件 */
.block { }
/* Element:组件内元素(双下划线) */
.block__element { }
/* Modifier:变体(双连字符) */
.block--modifier { }
.block__element--modifier { }
<div class="card card--featured">
<h2 class="card__title">标题</h2>
<p class="card__description">描述</p>
<button class="card__button card__button--primary">点击</button>
</div>
BEM 优缺点:
- 优点:命名自解释、无层级嵌套、可预测
- 缺点:类名冗长、不适合深层嵌套组件
CSS Modules:
/* 文件:Button.module.css */
.button { color: red; }
.active { font-weight: bold; }
// React 中使用
import styles from './Button.module.css';
// styles.button → 生成唯一类名如 Button_button_1a2b3c
<button className={`${styles.button} ${isActive ? styles.active : ''}`} />
CSS-in-JS(styled-components / Emotion / linaria):
const Button = styled.button`
background: ${props => props.variant === 'primary' ? 'blue' : 'gray'};
color: white;
padding: 8px 16px;
border-radius: 4px;
&:hover {
opacity: 0.9;
}
`;
方案对比:
| 方案 | 作用域 | 动态样式 | 运行时开销 | 类型安全 |
|---|---|---|---|---|
| BEM | 手动 | 手动切换类 | 无 | 无 |
| CSS Modules | 自动(文件级) | 类切换 | 无 | 部分(.module.css.d.ts) |
| CSS-in-JS | 自动 | 直接 props | 有 | 可 |
| Utility-first | 全局 | 组合类 | 无 | 可 |
预处理器
Sass(SCSS)核心功能:
// 变量
$primary: #007bff;
$spacing: 16px;
// 嵌套(注意不要超过 3 层)
.card {
padding: $spacing;
&__title { font-size: 1.25rem; }
&--featured { border-color: $primary; }
&:hover { box-shadow: 0 2px 8px rgba(0,0,0,.15); }
}
// Mixin(可传参)
@mixin respond-to($breakpoint) {
@if $breakpoint == 'md' {
@media (min-width: 768px) { @content; }
} @else if $breakpoint == 'lg' {
@media (min-width: 1024px) { @content; }
}
}
.sidebar { display: none; @include respond-to('md') { display: block; } }
// 继承(@extend)
.error { border: 1px solid red; color: red; }
.serious-error { @extend .error; font-weight: bold; }
// 函数
@function rem($px) {
@return $px / 16 * 1rem;
}
body { font-size: rem(16); }
Less 核心功能(类似但不完全兼容):
@primary: #007bff;
.box-shadow(@x, @y, @blur, @color) {
box-shadow: @x @y @blur @color;
}
.card {
.box-shadow(0, 2px, 4px, rgba(0,0,0,.1));
}
PostCSS
PostCSS 是基于插件的 CSS 处理工具,不是预处理器。
常用插件:
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer'), // 自动添加厂商前缀
require('postcss-preset-env'), // 使用未来 CSS 语法
require('cssnano'), // 压缩
require('postcss-import'), // 合并 @import 为单个文件
require('postcss-nesting'), // 原生 CSS 嵌套
]
};
CSS 变量(自定义属性)
:root {
--primary: #007bff;
--primary-hover: #0056b3;
--spacing-sm: 8px;
--spacing-md: 16px;
--font-size-base: 1rem;
--border-radius: 4px;
--shadow: 0 2px 4px rgba(0,0,0,.1);
}
.button {
background: var(--primary);
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--border-radius);
font-size: var(--font-size-base, 16px); /* 第二个参数是 fallback */
}
/* 作用域覆盖 */
.dark-theme {
--primary: #66b0ff;
}
/* 可以用 JS 动态修改 */
document.documentElement.style.setProperty('--primary', '#ff6600');
/* calc 结合变量 */
.element {
width: calc(var(--spacing-md) * 10);
}
CSS 变量 vs SCSS 变量:
| 特性 | CSS 变量 | SCSS 变量 |
|---|---|---|
| 作用域 | 继承(级联) | 编译时词法作用域 |
| 运行时修改 | 支持(JS 或媒体查询) | 不支持 |
| 媒体查询 | 可覆盖 | 无法覆盖 |
| 类型 | 任意值 | 具体值 |
| 动效 transition | 可过渡 | 不可 |
@layer 级联层
/* 定义层级顺序(先定义的优先级低) */
@layer reset, base, components, utilities;
/* 层内定义 */
@layer reset {
*, *::before, *::after { box-sizing: border-box; margin: 0; }
}
@layer base {
body { font-family: sans-serif; line-height: 1.6; }
a { color: blue; }
}
@layer components {
.card { padding: 16px; border: 1px solid; }
}
@layer utilities {
.mt-4 { margin-top: 16px; }
.text-center { text-align: center; }
}
@layer 意义:解决 CSS 优先级冲突,让低优先级的 reset 不会覆盖组件样式,不再依赖选择器权重或 !important。
新特性
:has() 选择器(CSS 选择器第 4 级)
/* 父选择器:选择包含某后代的元素 */
.card:has(.featured) { border-color: gold; }
figure:has(figcaption) { background: #f5f5f5; }
/* 兄弟选择 */
h2:has(+ p) { margin-bottom: 0; }
/* 条件选择 */
.form-group:has(:invalid) label { color: red; }
/* 数量查询 */
.row:has(> :nth-child(3):last-child) { /* 恰好 3 个子项 */ }
@container(容器查询)
@container (min-width: 400px) {
/* 组件级响应式 */
}
View Transitions API
// SPA 页面过渡
document.startViewTransition(() => {
updateDOMForNewPage();
});
/* CSS */
::view-transition-old(root) {
animation: fadeOut 0.3s ease;
}
::view-transition-new(root) {
animation: fadeIn 0.3s ease;
}
color-mix()
/* 颜色混合 */
.element {
background: color-mix(in srgb, red, blue);
/* 比例控制 */
background: color-mix(in srgb, red 30%, blue);
background: color-mix(in hsl, var(--primary), white 50%);
}
CSS Nesting(原生嵌套)
.card {
padding: 16px;
& .title { font-size: 1.25rem; } /* 嵌套选择器 */
& > .body { margin-top: 8px; }
&:hover { box-shadow: 0 2px 4px; } /* & 代表父选择器 */
@media (width > 768px) { /* 嵌套媒体查询 */
padding: 24px;
}
}