CSS 新时代:浏览器原生能力如何重塑前端开发范式

前言

曾经,前端开发者的一大痛点是:写 CSS 需要各种预处理器才能获得"现代"体验。Sass/SCSS 提供变量和嵌套,PostCSS 提供未来的语法,Tailwind 提供原子化哲学------它们本质上都是对 CSS 设计能力的"补偿"。

2024-2026 年,情况发生了根本性改变 。一系列浏览器原生 API 的成熟,让 CSS 从一个"样式描述语言"进化为一个强大的声明式编程体系。许多原本需要 JavaScript 实现的能力,如今可以纯粹用 CSS 完成。

本文将从原理到实战,深度剖析这些革命性新特性,并探讨它们如何改变前端架构。


一、CSS 的能力边界正在消失

1.1 从前到后的能力迁移

scss 复制代码
以前需要 JS 的能力 → 现在浏览器原生支持

┌──────────────────────────────────────────────────────────────┐
│  JS 实现                          →  CSS 原生替代             │
├──────────────────────────────────────────────────────────────┤
│  响应式布局(JS 监听 resize)     →  Container Queries       │
│  页面过渡动画(单页应用路由)     →  View Transitions API    │
│  父元素选择器                    →  :has() 选择器            │
│  滚动驱动动画(Intersection API) →  Scroll-Driven Animations│
│  动态颜色计算                    →  CSS 颜色函数             │
│  自定义动画曲线                  →  @property + Houdini      │
│  嵌套样式                        →  CSS Nesting              │
│  弹出层/对话框                    →  Popover API              │
└──────────────────────────────────────────────────────────────┘

这意味着什么?

  • 更少的 JavaScript → 更小的 Bundle
  • 浏览器原生实现 → 更好的性能
  • 声明式写法 → 更少的 Bug
  • 标准 API → 更好的可维护性

二、Container Queries:真正的组件级响应式

2.1 传统媒体查询的局限

css 复制代码
/* 传统方式:基于视口宽度 */
@media (max-width: 640px) {
  .card {
    display: block;
  }
}

/* 问题:card 可能在任何宽度的容器中
   - 侧边栏中的 card(窄)   → 需要小屏样式
   - 主内容区的 card(宽)   → 需要大屏样式
   - 但视口宽度是一样的!
*/

2.2 容器查询的核心语法

css 复制代码
/* 1. 定义容器 */
.card-wrapper {
  container-type: inline-size;   /* 启用容器查询 */
  container-name: card-container; /* 命名容器(可选) */
}

/* 2. 基于容器宽度响应 */
@container card-container (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 16px;
  }
}

@container (max-width: 399px) {
  .card {
    display: flex;
    flex-direction: column;
  }
}

2.3 完整的组件级响应式案例

css 复制代码
/* ============================================================ */
/* 卡片组件:完全基于容器宽度自适应的响应式设计                    */
/* ============================================================ */

.product-card {
  container-type: inline-size;
  container-name: product;
}

/* 超小容器:堆叠布局 */
@container product (max-width: 250px) {
  .card-inner {
    flex-direction: column;
    padding: 12px;
  }
  .card-title { font-size: 14px; }
  .card-image { width: 100%; height: 120px; }
  .card-price { font-size: 16px; }
}

/* 小容器:水平布局 */
@container product (min-width: 251px) and (max-width: 400px) {
  .card-inner {
    flex-direction: row;
    gap: 12px;
  }
  .card-image { width: 100px; }
  .card-title { font-size: 15px; }
}

/* 中等容器:丰富展示 */
@container product (min-width: 401px) and (max-width: 600px) {
  .card-inner {
    flex-direction: row;
    gap: 20px;
  }
  .card-image { width: 180px; height: 200px; }
  .card-badge { display: block; }      /* 展示徽章 */
  .card-description { display: -webkit-box; -webkit-line-clamp: 2; }
}

/* 大容器:完整展示 */
@container product (min-width: 601px) {
  .card-inner {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 24px;
  }
  .card-image { height: 100%; }
  .card-description { -webkit-line-clamp: unset; }
  .card-tags { display: flex; }       /* 展示标签 */
  .card-actions { display: flex; }    /* 展示操作按钮 */
}

2.4 容器查询的实际价值

场景 传统方案 Container Queries
组件在不同布局中使用 需要 JS 计算或重复代码 自动感知容器宽度
构建组件库 必须带 props 控制变体 样式自包含
响应式表单 固定断点,布局受限 容器自适应
Dashboard 卡片 需要 resize 监听 纯 CSS

三、:has() 选择器:让 CSS 拥有"向上查找"的能力

3.1 CSS 选择器的历史性突破

传统 CSS 只能"向下"或"向后"选择。:has() 打破了这一限制,被称为 "CSS 的父选择器"

css 复制代码
/* 革命性的能力:根据子元素状态改变父元素样式 */

/* 包含图片的卡片 → 改变布局 */
.card:has(img) {
  display: grid;
  grid-template-columns: 200px 1fr;
}

/* 表单包含错误信息 → 高亮边框 */
.form-group:has(.error-message) {
  border-color: #dc2626;
}

/* 导航栏中有子菜单 → 显示箭头 */
.nav-item:has(.submenu)::after {
  content: '▾';
}

3.2 实战:智能表单系统

css 复制代码
/* ============================================================ */
/* 纯 CSS 实现智能表单验证反馈                                    */
/* ============================================================ */

.form-group {
  padding: 16px;
  border: 2px solid #e2e8f0;
  border-radius: 8px;
  transition: border-color 0.3s, box-shadow 0.3s;
}

/* 必填项有值 → 绿色边框 */
.form-group:has(input[required]:valid) {
  border-color: #16a34a;
  background: #f0fdf4;
}

/* 有任何无效输入 → 红色边框 */
.form-group:has(:user-invalid) {
  border-color: #dc2626;
  background: #fef2f2;
}

/* 聚焦时 → 蓝色高亮 */
.form-group:has(:focus-visible) {
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}

/* 禁用状态 → 灰色 */
.form-group:has(input:disabled) {
  opacity: 0.6;
  cursor: not-allowed;
}

/* 包含密码输入框 → 显示密码强度条 */
.form-group:has(input[type="password"])::after {
  content: '';
  display: block;
  height: 4px;
  border-radius: 2px;
  margin-top: 8px;
  background: linear-gradient(
    to right,
    #dc2626 0%,
    #dc2626 25%,
    #d97706 25%,
    #d97706 50%,
    #facc15 50%,
    #facc15 75%,
    #16a34a 75%
  );
}

3.3 更多创意用法

css 复制代码
/* 空状态检测 */
.todo-list:has(:not(li))::after {
  content: '暂无待办事项';
  display: block;
  text-align: center;
  color: #64748b;
  padding: 40px;
}

/* 数量感知布局 */
.grid:has(> :nth-child(4)) {
  /* 超过 4 个元素时改变布局 */
  grid-template-columns: repeat(4, 1fr);
}

.grid:has(> :only-child) {
  /* 只有一个子元素时居中 */
  place-items: center;
}

/* 相邻元素感应 */
.card:has(+ .card:hover) {
  /* 下一张卡片被 hover 时,当前卡片调整 */
  filter: brightness(0.95);
}

/* 暗色模式下的特定调整 */
:root:has(#dark-mode-toggle:checked) .card {
  background: #1e293b;
  border-color: #334155;
}

四、View Transitions API:原生页面过渡动画

4.1 告别第三方动画库

javascript 复制代码
// 传统 SPA 路由动画
import { AnimatePresence, motion } from 'framer-motion';
// 需要包裹所有路由,管理状态...

// 现在:浏览器原生支持
document.startViewTransition(() => {
  // 更新 DOM
  updatePageContent();
});

4.2 跨页面/跨组件的平滑过渡

css 复制代码
/* ============================================================ */
/* 产品列表 → 详情页 的原生过渡动画                               */
/* ============================================================ */

/* 给需要过渡的元素命名 */
.product-card {
  view-transition-name: product-card;
}

.product-image {
  view-transition-name: product-image;
}

.product-title {
  view-transition-name: product-title;
}

/* 自定义过渡动画 */
::view-transition-old(product-image) {
  animation: 300ms ease-out both fade-out-and-shrink;
}

::view-transition-new(product-image) {
  animation: 300ms ease-out both fade-in-and-grow;
}

@keyframes fade-out-and-shrink {
  to {
    opacity: 0;
    transform: scale(0.8);
  }
}

@keyframes fade-in-and-grow {
  from {
    opacity: 0;
    transform: scale(0.8);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

4.3 SPA 路由过渡完整实现

typescript 复制代码
// lib/view-transition.ts
// 封装 View Transition 工具函数

export function navigateWithTransition(
  navigate: () => void,
  transition?: {
    type?: 'slide' | 'fade' | 'morph';
    duration?: number;
  }
) {
  // 检查浏览器支持
  if (!document.startViewTransition) {
    navigate();
    return;
  }

  const { type = 'fade', duration = 250 } = transition ?? {};

  document.documentElement.dataset.transition = type;
  document.documentElement.style.setProperty(
    '--transition-duration',
    `${duration}ms`
  );

  const vt = document.startViewTransition(() => {
    navigate();
  });

  vt.ready.then(() => {
    document.documentElement.removeAttribute('data-transition');
  });
}
css 复制代码
/* app/transitions.css */
:root {
  --transition-duration: 250ms;
}

/* 页面级过渡 */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

::view-transition-old(root) {
  animation: var(--transition-duration) ease-out both fade-out;
}

::view-transition-new(root) {
  animation: var(--transition-duration) ease-out both fade-in;
}

/* 滑动过渡 */
[data-transition="slide"]::view-transition-old(root) {
  animation: var(--transition-duration) ease-out both slide-out-left;
}

[data-transition="slide"]::view-transition-new(root) {
  animation: var(--transition-duration) ease-out both slide-in-right;
}

@keyframes fade-out {
  to { opacity: 0; }
}

@keyframes fade-in {
  from { opacity: 0; }
}

@keyframes slide-out-left {
  to { transform: translateX(-30px); opacity: 0; }
}

@keyframes slide-in-right {
  from { transform: translateX(30px); opacity: 0; }
}

五、Scroll-Driven Animations:让动画跟随滚动

5.1 告别 Intersection Observer

css 复制代码
/* 
  以前:需要 JS 监听滚动位置,计算进度,设置样式
  现在:纯 CSS,声明式
*/

/* 滚动进度条 */
@keyframes grow-progress {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  transform-origin: left;

  animation: grow-progress linear;
  animation-timeline: scroll();
}

5.2 视口滚动驱动的入场动画

css 复制代码
/* ============================================================ */
/* 元素进入视口时的入场动画                                      */
/* ============================================================ */

@keyframes fade-in-up {
  from {
    opacity: 0;
    transform: translateY(40px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.card {
  /* 基于视口的滚动时间线 */
  animation: fade-in-up linear;
  animation-timeline: view();
  animation-range: entry 0% entry 100%;
}

/* 延迟入场 */
.card:nth-child(2) {
  animation-range: entry 10% entry 100%;
}

.card:nth-child(3) {
  animation-range: entry 20% entry 100%;
}

/* 视差效果 */
.hero-image {
  animation: slide-up linear;
  animation-timeline: scroll();
  animation-range: 0% 100%;
}

@keyframes slide-up {
  to { transform: translateY(-20%); }
}

5.3 横向滚动故事板

css 复制代码
.story {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  display: flex;
}

.story-panel {
  flex: 0 0 100%;
  scroll-snap-align: start;
  
  /* 面板切换动画 */
  view-timeline-name: --panel;
  view-timeline-axis: inline;
}

/* 当前面板的内容动画 */
.story-panel .content {
  animation: reveal linear;
  animation-timeline: --panel;
  animation-range: entry 25% entry 100%;
}

@keyframes reveal {
  from {
    opacity: 0;
    clip-path: inset(0 50% 0 50%);
  }
  to {
    opacity: 1;
    clip-path: inset(0 0 0 0);
  }
}

六、CSS Nesting:原生的嵌套语法

6.1 告别 Sass 的必要性

css 复制代码
/* 以前只能在 Sass 中写 */
.card {
  padding: 24px;
  
  & .title {
    font-size: 18px;
    font-weight: 600;
  }
  
  & .body {
    margin-top: 12px;
  }
  
  &:hover {
    background: #f8fafc;
  }
  
  @media (min-width: 768px) {
    display: flex;
  }
}

/* 现在:浏览器原生支持! */
.card {
  padding: 24px;
  
  .title {
    font-size: 18px;
    font-weight: 600;
  }
  
  .body {
    margin-top: 12px;
  }
  
  &:hover {
    background: #f8fafc;
  }
  
  @media (min-width: 768px) {
    display: flex;
  }
}

6.2 嵌套与容器查询的结合

css 复制代码
.dashboard {
  container-type: inline-size;
  
  .grid {
    display: grid;
    gap: 16px;
    
    /* 传统媒体查询也可以嵌套 */
    @container (min-width: 600px) {
      grid-template-columns: repeat(2, 1fr);
    }
    
    @container (min-width: 900px) {
      grid-template-columns: repeat(3, 1fr);
    }
    
    .card {
      padding: 20px;
      border-radius: 12px;
      
      &:has(.chart) {
        min-height: 300px;
      }
      
      .header {
        display: flex;
        justify-content: space-between;
        
        h3 { font-size: 16px; }
        
        .actions {
          display: flex;
          gap: 8px;
          
          button {
            padding: 4px 12px;
            border-radius: 6px;
            
            &:hover { opacity: 0.8; }
            &.active { background: var(--primary); }
          }
        }
      }
    }
  }
}

七、颜色系统现代化

7.1 从 HEX/RGB 到现代颜色体系

css 复制代码
:root {
  /* HSL:语义化颜色操作 */
  --primary: hsl(221 83% 53%);
  --primary-light: hsl(221 83% 93%);
  --primary-dark: hsl(221 83% 33%);
  
  /* oklch:感知均匀的色彩空间 */
  --brand: oklch(0.5 0.2 250);
  
  /* color-mix:原生颜色混合 */
  --primary-50: color-mix(in srgb, var(--primary) 50%, white);
  --primary-900: color-mix(in srgb, var(--primary) 50%, black);
}

/* 自动生成完整调色板 */
.color-swatch {
  /* light-dark():自动切换深浅色 */
  background: light-dark(#ffffff, #1a1a1a);
  color: light-dark(#1a1a1a, #ffffff);
  
  /* color-contrast:自动选择最高对比度 */
  accent-color: color-contrast(var(--bg) vs #2563eb, #7c3aed, #0891b2);
}

7.2 动态主题系统

css 复制代码
:root {
  /* 基础色 */
  --hue: 221;
  --saturation: 83%;
  
  /* 自动派生的设计令牌 */
  --color-primary: hsl(var(--hue) var(--saturation) 53%);
  --color-primary-hover: hsl(var(--hue) var(--saturation) 43%);
  --color-primary-light: hsl(var(--hue) var(--saturation) 93%);
  --color-primary-dark: hsl(var(--hue) var(--saturation) 33%);
  
  --color-bg: hsl(var(--hue) 30% 98%);
  --color-surface: hsl(var(--hue) 20% 100%);
  --color-text: hsl(var(--hue) 30% 10%);
  --color-border: hsl(var(--hue) 20% 90%);
}

/* 换一整套主题只需改变 --hue */
[data-theme="purple"] { --hue: 280; }
[data-theme="green"]  { --hue: 142; }
[data-theme="orange"] { --hue: 26; }

/* 暗色模式 */
@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: hsl(var(--hue) 30% 8%);
    --color-surface: hsl(var(--hue) 20% 12%);
    --color-text: hsl(var(--hue) 20% 90%);
    --color-border: hsl(var(--hue) 15% 20%);
  }
}

八、Popover API:原生的弹出层

xml 复制代码
<!-- 
  以前:需要第三方库(Radix UI、Headless UI)或手写几百行 JS
  现在:浏览器原生支持
-->

<!-- 简单 Tooltip -->
<button popovertarget="tooltip" class="btn">
  帮助
</button>
<div id="tooltip" popover>
  <p>这是帮助提示信息</p>
</div>

<!-- 下拉菜单 -->
<button popovertarget="menu">选项</button>
<menu id="menu" popover>
  <li><button>编辑</button></li>
  <li><button>复制</button></li>
  <li><button>删除</button></li>
</menu>
css 复制代码
/* 动画效果 */
[popover] {
  /* 默认样式 */
  border: none;
  border-radius: 8px;
  padding: 8px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
  
  /* 打开/关闭动画 */
  opacity: 0;
  transform: scale(0.95) translateY(-5px);
  transition: 
    opacity 0.2s,
    transform 0.2s,
    overlay 0.2s allow-discrete,
    display 0.2s allow-discrete;
}

/* 打开状态 */
[popover]:popover-open {
  opacity: 1;
  transform: scale(1) translateY(0);
}

/* 关闭动画 */
@starting-style {
  [popover]:popover-open {
    opacity: 0;
    transform: scale(0.95) translateY(-5px);
  }
}

/* 轻量遮罩(借助 ::backdrop) */
[popover]::backdrop {
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(2px);
}

九、@property:自定义属性的类型安全

9.1 让 CSS 变量支持动画

css 复制代码
/* 普通 CSS 变量无法做动画 */
/* --angle: 0deg;  ← 浏览器不知道这是什么类型 */

/* @property 给它加上类型 */
@property --gradient-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

/* 现在可以动画了! */
.animated-card {
  --gradient-angle: 0deg;
  
  background: conic-gradient(
    from var(--gradient-angle),
    var(--primary) 0%,
    transparent 20%,
    var(--primary) 40%,
    transparent 60%,
    var(--primary) 80%
  );
  
  transition: --gradient-angle 0.5s;
}

.animated-card:hover {
  --gradient-angle: 360deg;
}

9.2 完整的光影边框效果

css 复制代码
@property --border-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

@keyframes border-spin {
  to { --border-angle: 360deg; }
}

.glow-card {
  position: relative;
  
  /* 旋转渐变边框 */
  &::before {
    content: '';
    position: absolute;
    inset: -2px;
    border-radius: inherit;
    background: conic-gradient(
      from var(--border-angle),
      #667eea,
      #764ba2,
      #f093fb,
      #667eea
    );
    animation: border-spin 3s linear infinite;
    z-index: -1;
  }
}

十、对前端架构的影响

10.1 技术选型的变化

sql 复制代码
Before(2022)
├── Sass/SCSS:变量 + 嵌套 + Mixin
├── PostCSS:未来语法转译
├── Framer Motion:页面动画
├── Intersection Observer:滚动动画
├── Radix/Headless UI:弹出层/Dialog
├── 第三方库:Tooltip、Dropdown
└── JS 响应式逻辑:适配容器宽度

After(2026)
├── CSS 原生嵌套                   → 替代 Sass
├── CSS 原生嵌套 + @property       → 替代部分 PostCSS
├── View Transitions API           → 替代 Framer Motion 基础功能
├── Scroll-Driven Animations       → 替代 Intersection Observer
├── Popover API                    → 替代弹出层库
├── Container Queries              → 替代 JS 响应式
└── :has() 选择器                  → 纯 CSS 状态管理

10.2 Bundle 体积的实际影响

sql 复制代码
一个典型 Dashboard 页面

Before:
  framer-motion:        38KB
  react-intersection-observer: 4KB
  @radix-ui/react-popover:   12KB
  @radix-ui/react-tooltip:   8KB
  Scroll/view 控制逻辑:      3KB
  ─────────────────────────
  总计:                   65KB

After (使用浏览器原生 API):
  CSS 实现动画 + 滚动控制:   0KB (浏览器内置)
  Popover API:               0KB (浏览器内置)
  View Transitions:          0KB (浏览器内置)
  ─────────────────────────
  总计:                    0KB (这些功能的 JS 归零)

10.3 渐进式迁移策略

scss 复制代码
阶段一:简单替换(零风险)
├─ Sass 嵌套 → CSS 原生嵌套
├─ 颜色主题 → oklch + color-mix
└─ :has() 替代传统的相邻选择器技巧

阶段二:能力增强(业务价值明确)
├─ 响应式 → Container Queries
├─ 表单验证 → :has() + :user-invalid
└─ 弹出层 → Popover API

阶段三:范式升级(需要设计评审)
├─ 动画 → View Transitions + Scroll-Driven
├─ 自定义动画 → @property
└─ 统一设计令牌 → 原生 CSS 变量 + 类型定义

十一、兼容性与实践建议

11.1 当前浏览器支持情况(2026)

特性 Chrome Safari Firefox Edge
Container Queries ✅ 105+ ✅ 16+ ✅ 110+ ✅ 105+
:has() 选择器 ✅ 105+ ✅ 15.4+ ✅ 121+ ✅ 105+
View Transitions API ✅ 111+ ✅ 18+ 🔜 ✅ 111+
Scroll-Driven Animations ✅ 115+ 🔜 🔜 ✅ 115+
CSS Nesting ✅ 120+ ✅ 17.2+ ✅ 117+ ✅ 120+
Popover API ✅ 114+ ✅ 17+ 🔜 ✅ 114+
@property ✅ 85+ ✅ 15.4+ ✅ 128+ ✅ 85+
color-mix() ✅ 111+ ✅ 16.2+ ✅ 113+ ✅ 111+

11.2 渐进增强的最佳实践

css 复制代码
/* 利用 CSS 的回退机制优雅降级 */

/* 1. Container Queries 降级 */
.card {
  /* 基础样式(所有浏览器)*/
  display: flex;
  flex-direction: column;
}

@supports (container-type: inline-size) {
  /* 增强样式(现代浏览器)*/
  .card-wrapper {
    container-type: inline-size;
  }
  
  @container (min-width: 400px) {
    .card {
      flex-direction: row;
    }
  }
}

/* 2. View Transitions 降级 */
@supports (view-transition-name: none) {
  .animated-element {
    view-transition-name: element;
  }
  
  ::view-transition-old(element) {
    animation: fade-out 0.3s ease-out;
  }
}

/* 3. Scroll-Driven 降级 */
@supports (animation-timeline: scroll()) {
  .scroll-progress {
    animation: grow-progress linear;
    animation-timeline: scroll();
  }
}

@supports not (animation-timeline: scroll()) {
  /* 回退:使用 JS 或静态样式 */
  .scroll-progress { display: none; }
}

结语

CSS 的这次进化不是"增加几个新属性"那么简单,而是从根本上改变了前端开发的范式:

scss 复制代码
传统前端                              现代前端
────────                              ────────
JS 驱动动画       ──→                 CSS 声明式动画
JS 监听响应式     ──→                 Container Queries
JS 状态关联样式   ──→                 :has() 选择器
JS 路由过渡       ──→                 View Transitions API
第三方 UI 库      ──→                 Popover API
预处理器         ──→                 原生 CSS

核心启示:

  1. 更少的 JS = 更好的性能 ------ 浏览器原生实现的性能远超 JS 模拟
  2. 声明式 = 更少的 Bug ------ CSS 的声明式特性天然适合 UI 描述
  3. 标准化 = 更好的未来 ------ 今天学的新 CSS,明天就能在项目中用
  4. 关注浏览器的能力边界 ------ 很多"必须用 JS"的假设已经过时

CSS 不再是"给 HTML 上色"的工具,它正在成为一个完整的、声明式的 UI 编程体系。对于前端开发者来说,重新审视 CSS 的能力,可能是 2026 年最高 ROI 的技术投资。


参考资源:MDN CSS 文档web.dev 新 CSS 特性指南Can I Use

相关推荐
不会写DN1 小时前
固定背景图不随页面滚动的完美方案
前端
天蓝色的鱼鱼1 小时前
Vite 8 换上 Rolldown 后,前端构建真的会快很多吗?
前端·vite
梦曦i1 小时前
全面解析uni-router v1.2.0功能
前端·uni-app
Yiyaoshujuku1 小时前
化学谱图数据API接口,数据字段一览!
linux·服务器·前端
雮尘2 小时前
LangGraph 与 LangSmith 入门教程(JS/TS 版)
前端·人工智能·langchain
英勇无比的消炎药2 小时前
新手必看玩转TinyRobot一定要避开这些坑
前端·vue.js
持敬chijing2 小时前
Web渗透之前后端漏洞-文件上传漏洞-过滤绕过与配置文件漏洞-条件竞争漏洞
前端·安全·web安全·网络安全·网络攻击模型·安全威胁分析
尼斯湖皮皮怪2 小时前
iceCoder:验收门控深度分析
前端·agent
周庆猛2 小时前
Babylon.js 多灯场景在 Windows 上报错:VERTEX shader uniform block count exceeds GL_MAX_VE
前端·数据可视化