-
网站性能是影响用户体验和搜索引擎排名的关键因素。本文将介绍现代网站性能优化的实用技巧,涵盖资源加载、代码优化、缓存策略等多个方面,帮助你打造更快、更流畅的网站。一、核心优化指标LCP (Largest Contentful Paint):最大内容绘制时间,衡量页面加载速度;FID (First Input Delay):首次输入延迟,衡量页面交互响应速度;CLS (Cumulative Layout Shift):累积布局偏移,衡量页面视觉稳定性;FCP (First Contentful Paint):首次内容绘制时间,衡量页面首次渲染速度。二、资源加载优化图片优化<!-- 使用WebP格式图片,体积更小 --> <picture> <source srcset="image.webp" type="image/webp"> <source srcset="image.jpg" type="image/jpeg"> <img src="image.jpg" alt="图片描述" loading="lazy"> </picture> <!-- 响应式图片 --> <img srcset="small.jpg 480w, medium.jpg 800w, large.jpg 1200w" sizes="(max-width: 480px) 480px, (max-width: 800px) 800px, 1200px" src="large.jpg" alt="图片描述">字体优化// 动态导入,实现代码分割 import('./lazy-component.js') .then(module => { const LazyComponent = module.default; // 使用懒加载组件 }) .catch(err => console.error('加载组件失败:', err)); // 路由懒加载(以Vue.js为例) const routes = [ { path: '/about', name: 'About', component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ];三、代码优化CSS 优化/* 删除未使用的CSS(可以使用PurgeCSS工具) */ /* 使用CSS变量,减少重复代码 */ :root { --primary-color: #165DFF; --secondary-color: #36CFC9; --text-color: #333333; } /* 使用CSS Grid和Flexbox替代传统布局,减少代码量 */ .container { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; }JavaScript 优化// 防抖函数,减少高频事件触发 function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } // 节流函数,限制函数执行频率 function throttle(func, limit) { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } } } // 使用requestAnimationFrame优化动画 function animate() { // 动画逻辑 requestAnimationFrame(animate); } requestAnimationFrame(animate);四、缓存策略优化浏览器缓存// 服务器端设置缓存头(以Node.js为例) app.use((req, res, next) => { // 静态资源缓存1年 if (req.url.match(/^\/(css|js|images|fonts)/)) { res.setHeader('Cache-Control', 'public, max-age=31536000, immutable'); } next(); });Service Worker 缓存// 注册Service Worker if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/service-worker.js') .then(registration => { console.log('Service Worker注册成功:', registration.scope); }) .catch(err => { console.log('Service Worker注册失败:', err); }); }); } // Service Worker缓存策略 self.addEventListener('fetch', event => { if (event.request.destination === 'image') { event.respondWith( caches.open('images-v1') .then(cache => cache.match(event.request)) .then(response => response || fetch(event.request)) ); } });五、性能监控// 使用Performance API监控页面性能 window.addEventListener('load', () => { // 测量FCP new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { if (entry.name === 'first-contentful-paint') { console.log('FCP:', entry.startTime); } } }).observe({entryTypes: ['paint']}); // 测量LCP new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); const lastEntry = entries[entries.length - 1]; console.log('LCP:', lastEntry.startTime); }).observe({entryTypes: ['largest-contentful-paint']}); // 测量CLS let clsValue = 0; new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { if (!entry.hadRecentInput) { clsValue += entry.value; console.log('CLS:', clsValue); } } }).observe({entryTypes: ['layout-shift']}); });六、总结网站性能优化是一个持续的过程,需要从多个方面入手,结合工具和监控数据,不断优化和改进。通过以上优化方案,可以显著提升网站的加载速度、交互响应速度和视觉稳定性,为用户提供更好的体验。
-
XSS(跨站脚本攻击)是前端开发中最常见的安全漏洞之一,攻击者通过在网页中注入恶意脚本,窃取用户信息、伪造用户操作等。本文将介绍 5 种实用的 XSS 防护方案,帮助你构建更安全的前端应用。一、XSS 攻击的类型存储型 XSS:恶意脚本被存储在服务器端,当用户访问页面时被执行;反射型 XSS:恶意脚本通过 URL 参数传递,服务器直接反射回页面中执行;DOM 型 XSS:恶意脚本通过修改页面 DOM 结构来执行,不经过服务器端。二、防护方案 1:输入验证与过滤对用户输入的所有内容进行验证和过滤,只允许合法的字符和格式。// 过滤HTML标签 function sanitizeInput(input) { const div = document.createElement('div'); div.textContent = input; return div.innerHTML; } // 验证邮箱格式 function validateEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } // 验证URL格式 function validateUrl(url) { const urlRegex = /^(https?:\/\/)[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/; return urlRegex.test(url); }三、防护方案 2:输出编码在将用户输入的内容输出到页面时,进行适当的编码处理,防止恶意脚本被执行。// 过滤HTML标签 function sanitizeInput(input) { const div = document.createElement('div'); div.textContent = input; return div.innerHTML; } // 验证邮箱格式 function validateEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } // 验证URL格式 function validateUrl(url) { const urlRegex = /^(https?:\/\/)[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/; return urlRegex.test(url); }四、防护方案 3:使用 CSP(内容安全策略)通过设置 HTTP 头或 meta 标签,限制页面可以加载的资源和执行的脚本,防止恶意脚本的执行。<!-- 使用meta标签设置CSP --> <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https:; connect-src 'self' https:; frame-ancestors 'none'; form-action 'self';">五、防护方案 4:使用 HttpOnly 和 Secure Cookie设置 Cookie 的 HttpOnly 属性,防止通过 JavaScript 访问 Cookie;设置 Secure 属性,确保 Cookie 只通过 HTTPS 传输。// 服务器端设置Cookie(以Node.js为例) res.cookie('sessionId', 'your_session_id', { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'strict', maxAge: 24 * 60 * 60 * 1000 // 24小时 });六、防护方案 5:使用安全的 DOM 操作 API避免使用不安全的 DOM 操作 API,如innerHTML、outerHTML、document.write等,优先使用安全的 API。// 安全的文本插入 const element = document.getElementById('target'); element.textContent = userInput; // 安全,会自动转义 // 安全的属性设置 element.setAttribute('title', userInput); // 安全 element.src = userInput; // 不安全,需要先验证URL格式 // 安全的创建元素 const newElement = document.createElement('div'); newElement.textContent = userInput; element.appendChild(newElement); // 安全七、总结XSS 防护需要从输入验证、输出编码、安全策略等多个方面入手,形成多层次的防护体系。同时,需要定期进行安全测试和漏洞扫描,及时发现和修复潜在的安全问题。
-
作为前端开发者,我们总在与CSS布局“博弈”——要么被视口响应式的局限性束缚,要么为样式优先级冲突头疼,要么因复杂布局的对齐问题妥协。而CSS近年来的四大核心新特性——容器查询、层叠层、子网格、CSS Houdini,彻底打破了这些困境,让CSS从“被动适配”走向“主动掌控”。不同于单纯的语法介绍,这篇帖子全程聚焦「实战落地」,每个特性都搭配可直接复用的代码案例,覆盖日常开发中高频场景(组件适配、样式管理、复杂布局、动态效果),新手能快速上手,老手能直接套用,帮你真正把新特性转化为开发效率。一、容器查询(Container Queries):组件级自适应的“魔法”在容器查询出现前,我们做响应式只能依赖媒体查询(@media),但它的核心痛点的是「以视口为参照物」——只能全局控制,无法实现组件级的自适应。比如同一个卡片组件,在侧边栏、主内容区、弹窗中宽度不同,却要保持适配,媒体查询根本无法精准控制。容器查询的核心优势的是:以父容器为参照物,让组件根据自身所在容器的尺寸,自动调整样式,实现“组件自给自足”的自适应,无需依赖视口宽度,也不用写冗余的JavaScript监听 resize。实战案例:编辑器工具栏智能显隐(生产环境复用)场景:编辑器工具栏宽度变化时,时间信息自动显隐,无需JS干预。<template> <div class="top-function-show-area"> <div class="center-section">编辑器操作按钮</div> <!-- 时间信息根据容器宽度自动显隐 --> <div class="process-info"> 当前时间: {{ currentProcess.toFixed(2) }} 秒 / 总体时长: {{ totalProcess.toFixed(2) }} 秒 </div> </div> </template> <style scoped> /* 关键1:声明容器(必须指定明确宽度,否则查询无效) */ .top-function-show-area { width: 100%; container-type: inline-size; /* 声明容器,关注 inline 方向尺寸(宽度) */ container-name: toolbar; /* 可选:给容器命名,方便多容器区分 */ } /* 关键2:基于容器宽度做响应(容器宽度<800px时隐藏时间) */ @container toolbar (max-width: 799px) { .process-info { display: none; } } </style>高频实战场景延伸电商产品卡片:同一卡片在不同宽度的容器中(单列/双列/三列),自动调整布局和内容显隐(如下代码片段);后台表单:表单在弹窗、侧边栏、主内容区中,自动切换“标签+输入框”的排列方式(横向/纵向);数据仪表盘:组件根据父容器大小,自动调整图表尺寸和数据展示密度。/* 电商产品卡片容器查询示例 */ .product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); container-type: inline-size; /* 声明容器 */ } /* 容器宽度<600px:单列布局,隐藏描述 */ @container (max-width: 599px) { .product-grid { grid-template-columns: 1fr; } .product-desc { display: none; } } /* 600px≤容器宽度<1000px:两列布局 */ @container (min-width: 600px) and (max-width: 999px) { .product-grid { grid-template-columns: repeat(2, 1fr); } }核心总结:容器查询让响应式从“页面级”下沉到“组件级”,减少全局样式冲突,降低维护成本,局部重绘的特性也比媒体查询更高效。截至2026年,所有主流浏览器已全面支持,可放心在生产环境使用。二、层叠层(@layer):终结样式优先级的“混乱战场”做过大型项目的开发者都懂一个痛点:CSS样式优先级混乱,为了覆盖第三方库样式、组件样式,不得不写越来越复杂的选择器,甚至滥用 !important,导致样式维护成本飙升,多人协作时极易出现冲突。层叠层(@layer)的核心作用是:给样式分组分层,明确指定各层的优先级,浏览器按“层的声明顺序”从低到高应用样式(后声明的层优先级更高),同一层内仍遵循传统CSS优先级规则,彻底告别优先级“暗战”。实战案例:大型项目样式分层管理场景:将项目样式分为“基础层、组件层、工具类层、第三方库层”,确保工具类能覆盖组件样式,自定义样式能覆盖第三方库样式。/* 1. 声明层的优先级顺序(后声明的层,优先级更高) */ @layer third-party, base, components, utilities; /* 2. 第三方库样式(优先级最低,可被自定义样式覆盖) */ @layer third-party { @import "bootstrap.css"; /* 将第三方库导入指定层 */ } /* 3. 基础样式(重置样式、全局字体等) */ @layer base { * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: "Inter", sans-serif; font-size: 16px; } } /* 4. 组件样式(按钮、卡片等,优先级低于工具类) */ @layer components { .btn { padding: 8px 16px; border: none; border-radius: 4px; background: #6366f1; color: #fff; } .card { border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px; } } /* 5. 工具类样式(优先级最高,用于快速覆盖样式) */ @layer utilities { .hidden { display: none; } .text-center { text-align: center; } .btn-primary { background: #3b82f6; } /* 可直接覆盖components层的.btn样式 */ }高频实战场景延伸第三方库集成:将Bootstrap、Element Plus等第三方样式导入独立层,无需修改源码,只需调整层顺序就能实现自定义覆盖;主题切换:将浅色/深色主题样式放入独立层,通过动态调整层顺序或类名,实现无卡顿主题切换;团队协作:明确各成员负责的样式层(如A负责组件层,B负责工具类层),减少同名选择器冲突。核心总结:层叠层让样式管理从“混乱无序”走向“结构化”,无需依赖选择器权重和 !important,新手也能轻松掌控样式优先级,大型项目必备。三、子网格(Subgrid):解决嵌套网格对齐的“终极补丁”CSS Grid布局极大简化了页面排版,但在嵌套网格场景中,一直存在一个痛点:子网格(嵌套的grid容器)无法继承父网格的行列定义,导致子网格内部的元素无法与父网格精确对齐,只能手动计算尺寸,维护困难,尤其在响应式布局中极易崩塌。子网格(subgrid)的核心优势是:让子网格继承父网格的行列轨道,打破独立的网格上下文,实现嵌套元素与父网格的精准对齐,无需手动计算尺寸,大幅简化复杂布局的代码。实战案例:复杂数据表格的精准对齐场景:销售数据表格中,部分行需要拆分细分数据(如线上/线下销售额),要求细分数据与主表格的列精准对齐,无需手动计算列宽。<div class="sales-table"> <div class="table-header">日期</div> <div class="table-header">产品</div> <div class="table-header">销售额</div> <div class="table-header">利润</div> <div class="table-row"> <div>2026-02-25</div> <div>A产品</div> <div>10000</div> <div>2000</div> </div> <!-- 需拆分细分数据的行,使用子网格对齐 --> <div class="table-row subgrid-row"> <div>2026-02-26</div> <div>B产品</div> <div class="sales-details"> <div>线上:8000</div> <div>线下:2000</div> </div> <div class="profit-details"> <div>线上:1600</div> <div>线下:400</div> </div> </div> </div> <style> /* 父网格:定义4列,控制整个表格布局 */ .sales-table { display: grid; grid-template-columns: 1fr 1.5fr 1.5fr 1fr; /* 4列布局 */ gap: 10px; padding: 16px; border: 1px solid #e5e7eb; } /* 子网格行:继承父网格的列定义 */ .subgrid-row { display: grid; grid-column: 1 / span 4; /* 跨越父网格所有列 */ grid-template-columns: subgrid; /* 继承父网格的列轨道 */ } /* 细分数据容器:同样继承父网格列,实现精准对齐 */ .sales-details, .profit-details { display: grid; grid-template-columns: subgrid; /* 继承父网格对应列的轨道 */ gap: 5px; } .table-header { font-weight: 600; color: #1f2937; } </style>高频实战场景延伸产品卡片网格:所有卡片内部的图片、标题、价格,与父网格的行列精准对齐,视觉更统一;多级导航栏:嵌套的下拉菜单,与父导航栏的布局精准对齐,无需手动调整边距;仪表盘布局:多个嵌套的统计卡片,内部数据与父网格的网格线对齐,提升页面整洁度。核心总结:子网格是Grid布局的“补全方案”,解决了嵌套布局的对齐痛点,尤其适合复杂表格、卡片网格等场景,目前主流浏览器(Chrome、Firefox、Safari 16+)已全面支持。四、CSS Houdini:解锁浏览器底层能力,实现“自定义CSS”前面三个特性都是“优化现有CSS能力”,而CSS Houdini则是“扩展CSS能力”——它不是单一API,而是一套浏览器渲染管线的底层工具集,相当于打开了浏览器的“引擎盖”,让开发者能直接介入渲染流程(布局、绘制、合成),实现传统CSS无法完成的效果。核心优势:线程解耦(自定义逻辑运行在独立线程,不卡顿)、动态可编程(支持代码生成图形/动画)、原生兼容性(无需第三方库),彻底摆脱传统CSS的局限。其中,Paint API 是最常用、最易上手的Houdini能力,适合实现动态图形、自定义背景等效果,下面重点实战演示。实战案例:动态可配置波点背景(替代静态图片)场景:实现可通过CSS变量调整波点大小、颜色、间隙的动态背景,替代传统静态背景图,适配不同屏幕尺寸,且支持实时修改。步骤1:创建Paint Worklet(自定义绘制逻辑)// dot-pattern-worklet.js registerPaint('dot-pattern', class { // 声明需要读取的CSS自定义属性(传递波点参数) static get inputProperties() { return ['--dot-size', '--dot-color', '--dot-gap']; } // 核心绘制方法:ctx=绘图上下文,size=元素尺寸,props=CSS属性 paint(ctx, size, props) { // 解析CSS变量,设置默认值(避免未定义报错) const dotSize = parseInt(props.get('--dot-size')) || 8; const dotColor = props.get('--dot-color') || '#333'; const dotGap = parseInt(props.get('--dot-gap')) || 16; // 设置绘图样式 ctx.fillStyle = dotColor; // 循环绘制波点(横向+纵向排列) for (let x = 0; x < size.width; x += dotSize + dotGap) { for (let y = 0; y < size.height; y += dotSize + dotGap) { ctx.beginPath(); ctx.arc(x + dotSize/2, y + dotSize/2, dotSize/2, 0, 2 * Math.PI); ctx.fill(); } } } });步骤2:加载Worklet并应用到页面<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Houdini 动态波点背景</title> <style> .dot-background { width: 100vw; height: 100vh; /* 调用自定义Paint Worklet生成背景 */ background-image: paint(dot-pattern); /* 通过CSS变量控制波点参数(可动态修改) */ --dot-size: 12; --dot-color: #6366f1; --dot-gap: 20; } </style> </head> <body> <div class="dot-background"></div> <script> // 加载自定义Paint Worklet(需服务器环境,本地可用Live Server) if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('dot-pattern-worklet.js'); } </script> </body> </html>高频实战场景延伸自定义边框/阴影:实现渐变边框、不规则阴影,替代传统CSS border-shadow的局限;数据可视化:通过Paint API绘制简单图表(如进度条、环形图),无需依赖Chart.js;交互动画:结合Animation Worklet,实现不占用主线程的复杂动画(如视差滚动、跟随鼠标效果),避免卡顿。核心总结:CSS Houdini让开发者从“使用CSS”升级为“扩展CSS”,适合需要个性化动态效果、追求极致性能的场景,目前主流浏览器已支持核心API,可逐步在项目中落地。五、四大特性实战总结与兼容性说明1. 特性核心价值对比特性核心价值核心解决痛点容器查询组件级自适应媒体查询无法局部控制组件样式层叠层样式优先级可控样式冲突、优先级混乱、滥用!important子网格嵌套网格精准对齐子网格与父网格无法对齐,手动计算繁琐CSS Houdini扩展CSS能力传统CSS无法实现复杂动态效果、性能卡顿2. 浏览器兼容性(2026年最新)容器查询:Chrome 105+、Firefox 110+、Safari 16+,全面支持;层叠层:Chrome 99+、Firefox 97+、Safari 15.4+,无兼容性问题;子网格:Chrome 109+、Firefox 71+、Safari 16+,主流浏览器全覆盖;CSS Houdini(核心API):Chrome 65+、Firefox 70+、Safari 14.1+,Paint API可放心使用。3. 实战建议新手入门:先掌握「容器查询+层叠层」,这两个特性上手简单,能快速解决日常开发80%的问题;进阶提升:学习「子网格」优化复杂布局,减少冗余代码;高阶突破:尝试「CSS Houdini」,实现个性化动态效果,提升项目竞争力。
-
position:sticky是CSS中的一个定位属性,它允许元素在滚动时保持在特定位置,直到滚动到另一个指定位置。以下是对position:sticky的详细解释:一、工作原理position:sticky结合了position:relative和position:fixed的特点。当元素在屏幕上可见且未滚动到指定位置时,它的行为类似于position:relative,即相对于其正常位置进行定位。然而,一旦元素滚动到指定的偏移位置(如top: 0),它将“粘性定位”并停留在那里,类似于position:fixed,直到滚动到另一个指定的偏移位置或不再满足粘性定位的条件。二、使用条件指定偏移值:为了使用position:sticky,必须指定top、bottom、left或right中的至少一个值。这些值定义了元素相对于其最近的具有滚动条的祖先元素的偏移量。如果没有指定这些值中的任何一个,元素将仅处于相对定位状态,而不会表现为粘性定位。滚动容器:粘性定位的元素依赖于滚动容器的滚动行为。这个滚动容器是元素最近的具有滚动条的祖先元素。如果祖先元素没有滚动条或设置了overflow:hidden,则粘性定位可能无法生效。父元素高度:当使用top或bottom属性时,父元素的高度不能低于粘性元素在这些属性上设置的值。否则,当元素滚动到父元素的底部时,它将无法保持固定位置。三、注意事项兼容性:虽然现代浏览器大多支持position:sticky,但一些旧版本的浏览器(如Internet Explorer和早期版本的Edge)可能不支持该属性。因此,在使用时需要进行兼容性测试。层叠上下文:position:sticky会创建一个新的层叠上下文(stacking context),这意味着它会影响元素的堆叠顺序和z-index属性的行为。滚动容器高度:在某些情况下,滚动容器的高度可能会影响粘性元素的表现。因此,需要仔细考虑滚动容器的高度和粘性元素的位置关系。四、应用示例一个常见的应用场景是头部导航栏的粘性定位。当用户向下滚动页面时,导航栏会固定在页面的顶部,而当用户向上滚动时,导航栏会回到原来的位置。这可以通过给导航栏元素设置position:sticky和适当的top值来实现。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sticky Position Example</title> <style> .navbar { position: -webkit-sticky; /* Safari */ position: sticky; top: 0; background-color: #f1f1f1; padding: 10px 0; } .content { padding: 20px; height: 2000px; /* 为了演示滚动效果,设置较大的高度 */ } </style> </head> <body> <div class="navbar">Sticky Navbar</div> <div class="content"> <p>Scroll down to see the sticky effect.</p> <!-- 页面内容 --> </div> </body> </html>在上面的示例中,当用户向下滚动页面时,.navbar元素将固定在页面的顶部。当用户向上滚动时,它将回到原来的位置。综上所述,position:sticky是一个强大的CSS属性,它允许元素在滚动时保持在特定位置。然而,在使用时需要注意兼容性、父元素的高度和滚动容器的行为等因素。
-
css设置背景模糊周边有白色光晕,如何解决?<div class="img-box"> <img :src="xxx.png"> <div class="img-bg" :style="{'background-image': `url(`+ xxx.png+ `)`}"></div> </div>.img-box { width: 100%; height: 212px; text-align: center; position: relative; img { width: 100%; height: 100%; position: relative; z-index: 5; } .img-bg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-size: 200%; /* 放大两倍 */ background-position: center; background-repeat: no-repeat; filter: blur(20px); /* 添加20模糊效果 */ overflow: hidden; } .img-bg::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.6); /* 60%不透明度的黑色 */ z-index: 1; /* 确保蒙层在背景之上 */ } }需求:想要给一个展示图片的区域底部加一个该图片的放大后的背景,并模糊 20,并增加一个黑色 0.6 透明度的遮罩解决方案:使用backdrop-filter: blur(20px);但是注意,backdrop-filter 不能直接加在背景图本身样式上,会导致不生效。backdrop-filter 属性需要在具有定位的元素上使用,例如 position: relative 或 position: absolute;backdrop-filter应用于的元素需要有一个背景元素在其后,通常是该元素的父级元素。如果没有这样的背景元素,backdrop-filter将不会生效。确保父级元素有可见的背景内容。所以我们将backdrop-filter 放在 img-bg::before 里,即可生效:.img-bg::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.6); /* 60%不透明度的黑色 */ z-index: 1; /* 确保蒙层在背景之上 */ backdrop-filter: blur(20px); /* 添加20模糊效果 */ }
-
知识点: animation 时间函数 steps()。用 css3 模拟一个渐变式圆点加载效果。核心代码部分,简要说明了写法思路;完整代码在最后,可直接复制到本地运行。核心代码html 代码<div class="loading38"> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> </div>用8个 span 标签绘制8个圆点。css 部分代码.loading38 { --r-num: 45deg; /*定义角度值*/ width: 40px; height: 40px; position: relative; animation: loading38-eff 1s steps(8) both infinite; /*steps函数*/ } .load-span38{ width: 6px; height: 6px; display: block; border-radius: 3px; position: absolute; left: 17px; top: 0; transform-origin: 3px 20px; /*定义变形中心点*/ } .load-span38:nth-of-type(1){ transform: rotate(var(--r-num)); background: #2FACFD; } .load-span38:nth-of-type(2){ transform: rotate(calc(var(--r-num)*2)); background: #33B4FD; } .load-span38:nth-of-type(3){ transform: rotate(calc(var(--r-num)*3)); background: #38BEFE; } .load-span38:nth-of-type(4){ transform: rotate(calc(var(--r-num)*4)); background: #3ECAFE; } .load-span38:nth-of-type(5){ transform: rotate(calc(var(--r-num)*5)); background: #45D7FE; } .load-span38:nth-of-type(6){ transform: rotate(calc(var(--r-num)*6)); background: #4BE4FE; } .load-span38:nth-of-type(7){ transform: rotate(calc(var(--r-num)*7)); background: #52F1FF; } .load-span38:nth-of-type(8){ transform: rotate(calc(var(--r-num)*8)); background: #57FBFF; } @keyframes loading38-eff{ to { transform: rotate(0deg); } from { transform: rotate(-360deg); } }1、8个 span 绘制8个圆点,分别写上不同的背景色2、通过 transform-origin 属性来定义变形的中心点,然后给每个圆点计算角度变形(这里我定义的角度值为 (360°/8 = 45°)),注意这里的每次变形是基于上一个圆点的角度 +45deg3、最后给整体加上 animation 动画,并设置时间函数 steps() 为8,意思是分8次整体旋转完成 360deg完整代码如下html 页面<!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="style.css"> <title>渐变加载条</title> </head> <body> <div class="app"> <div class="loading38"> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> <span class="load-span38"></span> </div> </div> </body> </html>css 样式/** style.css **/ .app{ width: 100%; height: 100vh; background-color: #ffffff; position: relative; display: flex; justify-content: center; align-items: center; } .loading38 { --r-num: 45deg; /*定义角度值*/ width: 40px; height: 40px; position: relative; animation: loading38-eff 1s steps(8) both infinite; } .load-span38{ width: 6px; height: 6px; display: block; border-radius: 3px; position: absolute; left: 17px; top: 0; transform-origin: 3px 20px; } .load-span38:nth-of-type(1){ transform: rotate(var(--r-num)); background: #2FACFD; } .load-span38:nth-of-type(2){ transform: rotate(calc(var(--r-num)*2)); background: #33B4FD; } .load-span38:nth-of-type(3){ transform: rotate(calc(var(--r-num)*3)); background: #38BEFE; } .load-span38:nth-of-type(4){ transform: rotate(calc(var(--r-num)*4)); background: #3ECAFE; } .load-span38:nth-of-type(5){ transform: rotate(calc(var(--r-num)*5)); background: #45D7FE; } .load-span38:nth-of-type(6){ transform: rotate(calc(var(--r-num)*6)); background: #4BE4FE; } .load-span38:nth-of-type(7){ transform: rotate(calc(var(--r-num)*7)); background: #52F1FF; } .load-span38:nth-of-type(8){ transform: rotate(calc(var(--r-num)*8)); background: #57FBFF; } @keyframes loading38-eff{ to { transform: rotate(0deg); } from { transform: rotate(-360deg); } }
-
原创2022-07-26 17:54·程序员大鹏1 最近在网络上看到一个程序员表白代码,可爱有又不失调皮,让女生觉得我们做程序的也是很浪漫的;全部代码已经安排在文章末尾展示效果:html部分:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>js+html爱心表白动画特效</title> <link rel="stylesheet" href="css/love.css"> </head> <body> <div class="container" onselectstart="return false;" unselectable="on" style="-moz-user-select:none;"> <div class="body_left"> <img src="images/biubiubiu.gif" alt="" ondragstart='return false;'> </div> <div class="body_center love"> <div class="block"> <div class="div1"></div> <div class="div2"></div> <div class="div3"></div> <div class="div4"></div> </div> </div> </div> <div class="footer"> <div class="border"> <div class="border-top"></div> <div class="border-bottom"></div> </div> <div class="copyright"> <div id="version"><span>Version:</span> 0.0.2</div> <div id="createTime"><span>Time:</span> 2022/7/13</div> <div id="author"><span>© </span>psw</div> </div> </div> <script type="text/javascript" src="js/love.js"></script> </body> </html>js部分:const blk_pitn = { //各小方块相对【自身中心】的位置 -- 【自身中心】确定为#div22的方块 block1: [[0, 1], [0, 0], [-1, 0], [-1, -1]], block2: [[0, 1], [0, 0], [-1, 0], [0, -1]], block3: [[-1, 1], [0, 0], [-1, 0], [-1, -1]], block4: [[0, 1], [0, 0], [-1, 0], [-1, -1]], /* 1 */ block5: [[-1, 1], [0, 0], [-1, 0], [0, -1]], block6: [[0, -1], [0, 0], [-1, 0], [1, -1]], block7: [[-1, -1], [0, 0], [-1, 0], [1, 0]], block8: [[-1, 1], [0, 0], [-1, 0], [-1, -1]], /* 3 */ block9: [[0, -1], [0, 0], [-1, 0], [1, 0]], block10: [[-1, 1], [0, 0], [-1, 0], [1, 0]], block11: [[2, 0], [0, 0], [-1, 0], [1, 0]], /* — */ block12: [[0, 1], [0, 0], [-1, 0], [0, -1]], /* 2 */ block13: [[0, 1], [0, 0], [-1, 0], [-1, -1]], /* 1 */ block14: [[1, 1], [0, 0], [-1, 0], [1, 0]], block15: [[1, -1], [0, 0], [-1, 0], [1, 0]], block16: [[-1, -1], [0, 0], [-1, 0], [1, 0]], /* 7 */ block17: [[0, 1], [0, 0], [-1, 0], [0, -1]], /* 2 */ block18: [[0, 1], [0, 0], [-1, 0], [-1, -1]], /* 1 */ block19: [[0, -1], [0, 0], [-1, 0], [1, 0]], /* 9 */ block20: [[1, -1], [0, 0], [-1, 0], [1, 0]], block21: [[0, 1], [0, 0], [-1, 0], [-1, -1]], /* 1 */ block22: [[1, 1], [0, 0], [-1, 0], [1, 0]], /* 14 */ block23: [[0, 2], [0, 0], [0, -1], [0, 1]] /* | */ }, offset_pitn = { //各方块block相对【爱心中心】的位置 block1: [5, 3], block2: [5, 1], block3: [3, 4], block4: [3, 2], block5: [3, -1], block6: [2, 5], block7: [2, 1], block8: [1, -1], block9: [1, -3], block10: [1, 2], block11: [0, 3], block12: [0, 0], /* 【爱心中心】*/ block13: [-1, -4], block14: [0, -2], block15: [-2, 4], block16: [-2, 2], block17: [-2, 0], block18: [-3, -2], block19: [-4, 0], block20: [-3, 5], block21: [-5, 3], block22: [-4, 1], block23: [-6, 1] /* 因动画需要移动一个方块,故y轴坐标-1*/ }; let blocks = document.getElementsByClassName("block"), block = blocks[0], love = document.getElementsByClassName("love")[0], timer = null, index = 0, //记录拼接爱心的动画步骤 clone_block; //用于克隆方块 //1.移动方块的【自身中心】到【爱心中心】 block.style.top = "50%"; block.style.left = "50%"; block.style.margin = "-20px 0 0 -20px"; const block_left = parseFloat(window.getComputedStyle(block, null).left.slice(0, -2)), //【爱心中心】 左边距离父元素的距离 block_top = parseFloat(window.getComputedStyle(block, null).top.slice(0, -2)); //【爱心中心】 顶部距离父元素的距离 function Next() { if (++index >= 24) { clearInterval(timer); Rise(); // alert("已经是最后一个了!"); return; } block.style.visibility = "visible"; //升空动画前允许可见 //2.移动方块到指定的位置-即是移动【自身中心】到目标位置 block.style.left = block_left + 40 * offset_pitn["block" + index][0] + "px"; block.style.top = block_top - 40 * offset_pitn["block" + index][1] + "px"; for (let i = 0; i < block.children.length; i++) { // block.children[1].innerText = index; //编号便于调试 block.children[i].style.left = blk_pitn["block" + index][i][0] * -40 + "px"; /* -40 是因为逻辑坐标和浏览器的x,y轴方向不一样*/ block.children[i].style.top = blk_pitn["block" + index][i][1] * -40 + "px"; } //3.克隆方块—保存现在的位置 /* 一共会克隆23个方块,加上原先的一个方块block,共24个方块,即多出原先的block方块*/ clone_block = block.cloneNode(true); love.appendChild(clone_block); if (love.children.length >= 24) { blocks[blocks.length - 1].children[2].style.display = "none"; //去掉多余的小方块 block.style.display = "none"; //隐藏多出的block方块 } } function Rise() { //4.爱心升高,多出的那个小方块开始掉落 console.log("开始升空"); let timer2 = null, distance = 0; /* 升高时,移动的距离*/ const target = 120, /* 目标距离*/ speed = 1; /*移动速度*/ let love_top = parseFloat(window.getComputedStyle(love, null).top.slice(0, -2)); //爱心盒子距离屏幕顶部的距离 timer2 = setInterval(() => { distance += speed; // console.log(distance); if (distance >= target) { clearInterval(timer2); console.log("升空完毕"); } love.style.top = (love_top - distance) + "px"; }, 22); } window.onload = function () { setTimeout(() => { timer = setInterval(() => { Next(); }, 300); }, 12000); //gif图播放完毕所需时间为11.73s };css部分:* { margin: 0; padding: 0; border: 0; } .icon-love { width: 400px; } html, body { width: 100%; height: 100%; } body { /*background-color: skyblue;*/ overflow: hidden; /*隐藏超出的部分*/ } .container { width: 100%; height: 100%; position: relative; } /*---------------------- body_left -------------------------*/ .body_left { width: 300px; height: 300px; left: 0; bottom: 110px; position: absolute; z-index: 98; } /*---------------------- body_left -------------------------*/ /*---------------------- body_center -------------------------*/ .container .love { width: 520px; /* 13 * 40 */ height: 440px; /* 11 * 40 */ left: 50%; top: 50%; position: absolute; margin: -260px 0 0 -220px; /*background-color: gray;*/ } .love .block { right: 0; position: absolute; visibility: hidden; /*未开始升空动画前隐藏*/ background-color: yellow; } .love .block div { width: 40px; height: 40px; position: absolute; background: url("../images/heart.png") no-repeat; background-size: contain; /*background-color: #c40908;*/ /*border: 1px solid silver;*/ box-sizing: border-box; } /*---------------------- body_center -------------------------*/ /*---------------------- footer -------------------------*/ @keyframes border { 0% { width: 0; } 5% { width: 5%; } 10% { width: 10%; } 15% { width: 15%; } 20% { width: 20%; } 25% { width: 25%; } 30% { width: 30%; } 35% { width: 35%; } 40% { width: 40%; } 45% { width: 45%; } 50% { width: 50%; } 55% { width: 55%; } 60% { width: 60%; } 65% { width: 65%; } 70% { width: 70%; } 75% { width: 75%; } 80% { width: 80%; } 85% { width: 85%; } 90% { width: 90%; } 95% { width: 95%; } 100% { width: 100%; } } .footer { bottom: 30px; position: relative; z-index: 99; } .footer .border .border-top { /*width: 0;*/ /*display: inline-block;*/ border-top: 3px solid black; transform-origin: left center; -webkit-animation: border 312 linear; -o-animation: border 12s linear; animation: border 12s linear; animation-fill-mode : both; /*border-bottom: none;*/ } .footer .border .border-bottom { /*width: 0;*/ /*display: inline-block;*/ float: right; border-top: 3px solid red; transform-origin: right center; -webkit-animation: border 7s linear 12s; -o-animation: border 7s linear 12s; animation: border 7s linear 12s; animation-fill-mode : both; /*border-bottom: none;*/ } .footer .copyright { width: 100%; height: 30px; position: absolute; bottom: -30px; text-align: center; /*background-color: gray;*/ } .copyright div { width: 30%; line-height: 30px; display: inline-block; } .copyright div span { color: dimgray; } /*---------------------- footer -------------------------*/代码链接:cid:link_0
-
在 CSS 中可以使用 text-stroke 属性使文本更易读,它会向文本添加轮廓效果。 codeduidaima.comh1 {color: #fff;font-size: 80px;-webkit-text-stroke: 2px crimson;text-stroke: 2px crimson;}效果如下:注意如下这句: codeduidaima.comtext-stroke: 2px crimson;text-stroke 属性值中有两部分,第一部分是文字描边的宽度,第二部分是文字描边的颜色,crimson是深红色的意识。
-
说明使用 CSS 可以绘制出许多形状,比如三角形、梯形、圆形、椭圆,等 并不只是可以绘制矩形。下面来看看怎么实现这些形状的吧。为了容易理解,文章今天先从基本形状来讲,基本形状是比较容易实现的,而利用这些基本形状进行组合,就可以实现稍微复杂点的组合形状了。基本形状三角形.triangle { width: 0; height: 0; border: 50px solid blue; /* 通过改变边框颜色,可以改变三角形的方向 */ border-color: blue transparent transparent transparent;}梯形.trapzoid { width: 40px; height: 100px; border: 50px solid blue; border-color: transparent transparent blue transparent;}圆形.circle{ width:100px; height:100px; border-radius:50%; background:blue;}球体.sphere { height: 200px; width: 200px; border-radius: 50%; background: radial-gradient(circle at 70px 70px, #5cabff, #000);}椭圆.ellipse { width: 200px; height: 100px; border-radius: 50%; background: blue;}半圆.semicircle { width: 50px; height: 100px; /* "/"前四个值表示圆角的水平半径,后四个值表示圆角的垂直半径*/ border-radius: 200% 0 0 200% / 100% 0 0 100%; /* 效果和用%一样 */ /* border-radius: 50px 0 0 50px; */ background: blue;}菱形.rhombus { width: 200px; height: 200px; transform: rotateZ(45deg) skew(30deg, 30deg); background: blue;}组合形状心形心形是由两个圆形和一个矩形进行组合得到的。.heart { width: 100px; height: 100px; transform: rotateZ(45deg); background: red;}.heart::after,.heart::before { content: ""; width: 100%; height: 100%; border-radius: 50%; display: block; background: red; position: absolute; top: -50%; left: 0;}.heart::before { top: 0; left: -50%;}扇形扇形是由一个圆形和一个矩形进行组合得到的,用矩形遮住圆形的一部分就形成了扇形。.sector { width: 142px; height: 142px; background: #fff; border-radius: 50%; background-image: linear-gradient(to right, transparent 50%, #655 0);}.sector::before { content: ''; display: block; margin-left: 50%; height: 100%; width: 100%; background-color: inherit; transform-origin: left; /*调整角度,改变扇形大小*/ transform: rotate(230deg);}五边形五边形是由一个三角形和一个梯形进行组合得到的。.pentagonal { width: 100px; position: relative; border-width: 105px 50px 0; border-style: solid; border-color: blue transparent;}.pentagonal:before { content: ""; position: absolute; width: 0; height: 0; top: -185px; left: -50px; border-width: 0px 100px 80px; border-style: solid; border-color: transparent transparent blue;}
-
CSS规范BEM命名规范BEM 来自块(block)、元素(element)、修饰符(modifier)的缩写命名,约定模式:block:模块,名字单词间用 - 连接element:元素,模块的子元素,以 __ 与 block 连接modifier:修饰,模块的变体,定义特殊模块,以 -- 与 block 连接.block {} .block__element {} .block--modifier {}注释必要的地方务必要写注释。单行注释单独一行作为注释,//后面加空格代码及注释同行,//前后要加空格// 调用并获取用户基本信息 getUserInfo(); const MAX_COUNT = 3; // 最大统计数量多行注释不影响代码可读性,可考虑添加。主要涉及场景:业务逻辑性强关联代码难以理解/** * 代码注释1 * 代码注释2 */函数注释函数注释有业界统一的规范,复杂函数和类都有必要进行注释。/** * 以星号开头,紧跟一个空格,第一行为函数说明 * @param {类型} 参数 单独类型的参数 * @author 作者 创建时间 修改时间(短日期)改别人代码要留名(注意:不要写工号) * @example 举例(如果需要) */
-
具体代码如下所示:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> *{ margin: 0; padding: 0; box-sizing: border-box; font-family: "calisto mt"; } body{ display: flex; justify-content: center; align-items: center; min-height: 100vh; background: #111; } .scan{ position: relative; display: flex; flex-direction: column; align-items: center; } .scan .fingerprint{ position: relative; width: 200px; height: 280px; background: url(img/finger0.png) no-repeat; background-size: 100%; } .scan .fingerprint::before{ content: ''; position: absolute; top:0; left: 0; height: 100%; width: 100%; background: url(img/finger2.png) no-repeat; background-size: 100%; animation: animate 4s ease-in-out infinite; } .scan .fingerprint::after{ content: ''; position: absolute; top:0; left: 0; height: 8px; width: 100%; margin-top: -30px; background: #3fefef; border-radius: 8px; filter: drop-shadow(0 0 20px #3fefef) drop-shadow(0 0 60px #3fefef); animation: animate_line 4s ease-in-out infinite; } @keyframes animate_line{ 0%,100%{ top: 0; } 50%{ top: 100%; } } @keyframes animate{ 0%,100%{ opacity: 0; } 50%{ opacity: 1; } } .scan h3{ text-transform: unset; font-size: 2em; letter-spacing: 2px; margin-top: 20px; color: #3FEFEF; filter: drop-shadow(0 0 20px #3fefef) drop-shadow(0 0 60px #3fefef); animation: animate_txt 4s ease-in-out infinite; } @keyframes animate_txt{ 0%,100%{ opacity: 0; } 50%{ opacity: 1; } } </style> </head> <body> <div class="scan"> <div class="fingerprint"></div> <h3>Scanning...</h3> </div> </body></html>效果图:到此这篇关于CSS3实现指纹特效的文章就介绍到这了转载自https://www.jb51.net/css/816204.html
-
原文链接:https://blog.csdn.net/m0_50065287/article/details/122959703“回收旧电视、旧冰箱、旧电脑…”停、停、停!旧电脑可别送去回收,现在它们可以变身 Chromebook 了!本周一,谷歌宣布提前推出新版 Chrome OS——Chrome OS Flex,一款可下载至 Mac 或 Windows PC 上的 Chrome OS。一、从 2017 年开始布局Chrome OS Flex 并非凭空出世,早在 2017 年谷歌投资 Neverware 公司时其意图就有所体现。Neverware 成立于 2011 年,主要开发轻量级操作系统,在 2013 年推出采用私有技术的 PCReady 后投入 Chromium 开源项目,于 2015 年正式推出基于 Chromium 的软件应用 CloudReady,该应用可支持超过 350 款老旧 PC 或 Mac 设备运行 Chrome OS,将其融入 Chrome 生态,方便学校或企业的 IT 管理人员通过 Google Admin 控制台管理这些老旧设备。随后在 2020 年,谷歌更是直接收购 Neverware 将之纳入麾下。彼时 Neverware 表示“CloudReady 已是谷歌和 Chrome OS 团队的正式成员”,即 CloudReady 将会成为一个官方 Chrome OS 产品——而这也正是 Chrome OS Flex 的原型,它基本上就是 CloudReady 的谷歌官方版本。谷歌在介绍 Chrome OS Flex 的博文中表示:“CloudReady 帮助无数企业和学校实现了 PC 和 Mac 的现代化,所以我们也一直在努力将 CloudReady 的优势集成到新版的 Chrome OS 中。”二、“废物利用”起来启动时间久、系统被迫更新、安全插件版本低、管理愈发繁重等问题,很大程度上都是由于设备老旧而引起的,而这无疑对员工、学生和 IT 部门是一种很大的负担。相较于逐年老化变慢的 Windows PC 或升级 macOS 12 Monterey 都会“变砖”的旧 Mac,谷歌自信表示:“Chromebook 不会随着时间的推移而变慢,会一直保持最新状态、提供主动保护并且易于管理。 ”为此,谷歌希望能将这些旧 PC、Mac“废物利用”起来,将其变成一台 Chromebook,Chrome OS Flex 就是这个桥梁。虽然在官方博文中,谷歌声称 Chrome OS Flex 专为企业和学校设计,但总体来看,谷歌也将其视作旧 Mac 和 Windows PC 的解决方案,同样适用于无法升级 OS 最新版本的设备或没有预算更换设备的人。谷歌对 Chrome OS Flex 的评价很高,“可使老旧设备现代化”,还能“在 PC 和 Mac 上体验 Chrome OS 的优势所在”:快速、现代的工作体验:Chrome OS Flex 可在几秒钟内启动,且不会随着时间的推移而变慢。此外,支持对 Web 应用和虚拟化的快速访问,为用户提供直观、整洁的体验,并且系统更新在后台进行,即缩短了用户的停机时间。对安全问题提供最新保护:使用 Chrome OS Flex,只要定期安全更新,则无需防病毒软件。Chrome OS Flex 内置了针对病毒、勒索软件和网络钓鱼等安全隐患的保护功能,谷歌安全浏览会在用户访问恶意网站之前发出警告,甚至还可以通过远程擦除以防止设备上的数据丢失或被盗。轻松部署与管理:可通过 USB 或网络部署在几分钟内在设备上安装 Chrome OS Flex。登录后,用户原先的云配置文件将在设备上自动同步。对于 IT 管理人员来说,基于云的谷歌管理控制台也可提供强大而简单的管理体验。充分利用现有硬件的可持续解决方案:使用 Chrome OS Flex 可最大限度延长现有设备群的使用寿命,与其费心处理老化的 PC 和 Mac,使用现代、快速的操作系统对其进行更新可减少电子垃圾。不仅如此,Chrome OS Flex 基于与 Chrome OS 相同的代码库,发布及更新节奏将与 Chrome OS 保持一致,用户界面也相同,将提供官方 Chrome 浏览器、谷歌智能助理和跨设备功能,以此确保最终用户体验同步。目前,Chrome OS Flex 虽已官宣,但整体仍处于开发者预览版的早期阶段,为此谷歌呼吁广大开发者与之共同测试与反馈:只需一个 USB 驱动器和兼容的 PC 或 Mac 即可。用户可先直接从 USB 驱动器启动,无需安装即可无风险试用 Chrome OS Flex;准备就绪后,便可在 PC 或 Mac 上安装 Chrome OS Flex 以替换原本的操作系统,获得最佳体验。最后谷歌透露,Chrome OS Flex 正式稳定版预计将于几个月后推出,届时 CloudReady 用户将免费升级至 Chrome OS Flex。(欲试用 Chrome OS Flex 可访问以下网址:https://chromeenterprise.google/os/chromeosflex/)三、不过,据外媒 Ars Technica 从一位谷歌代表处得到的消息表示,因为谷歌“首先更关注操作系统的核心体验”,目前没有计划将 Google Play 商店和 Android 应用添加到 Chrome OS Flex 中,也不允许原先 CloudReady 家庭版支持的某些系统级访问,但未来这些情况是否会改善还未可知。对于谷歌这个旨在“废物利用”的系统,部分网友有些跃跃欲试:“我可能会尝试一下,目前我的笔记本电脑可以正常运行 Windows 11,但我很好奇使用更轻量级的操作系统会提高多少续航能力。”“我有几台苹果和微软拒绝支持的‘过时’设备,即便它们还可以完成大部分例行任务,但我想试试它。”但也有部分网友对 Chrome OS Flex 没有引入 Google Play 商店和 Android 应用这一点感到不满:“微软的 Windows 都在支持谷歌 Android 了,结果谷歌自己却没有将 Android 添加到自家操作系统里,多讽刺啊。”“谢谢,但我宁愿在我过时的 Mac 上安装一个轻量级的 Linux 也好过用这个具有超级限制性的操作系统。”还有人对谷歌这番“废物利用”的说辞提出质疑:“我希望谷歌为此成立一个组织来支持它的言论:他们的“支持”硬件列表现在看起来非常单薄,他们真的会将其扩展到所有机型吗?”(具体支持机型可参看:https://support.google.com/chromeosflex/answer/11513094#zippy=)“也就是说,谷歌明明有能力继续为旧 Chromebook 提供支持,至少可以为关键漏洞提供补丁,可他们却不这么做。”而对于这部分网友的质疑,谷歌在官方博文中已隐隐透露其推出 Chrome OS Flex 的另一目的:“凭借相似的最终用户和 IT 体验,当你准备购买新硬件时,可轻松地从 Chrome OS Flex 过渡到 Chrome OS 设备。”那么,你对 Chrome OS Flex 的看法如何?如电脑型号符合,你是否会尝试一番?参考链接:https://cloud.google.com/blog/products/chrome-enterprise/chrome-os-flexhttps://arstechnica.com/gadgets/2022/02/google-turns-old-macs-pcs-into-chromebooks-with-chrome-os-flex/?comments=1
-
【功能模块】获取css文件,失败【操作步骤&问题现象】1、portal页面请求index.css文件接口报418错误码2、导致页面展示有问题,麻烦帮忙拉会议解决下【截图信息】【日志信息】(可选,上传日志内容或者附件)顾庆耀/18068848554/guqingyao@chinasoftinc.com
-
如果实现单行文本的溢出显示省略号同学们应该都知道用text-overflow:ellipsis属性来,当然还需要加宽度width属来兼容部分浏览。实现方法:123overflow: hidden;text-overflow:ellipsis;white-space: nowrap;但是这个属性只支持单行文本的溢出显示省略号,如果我们要实现多行文本溢出显示省略号呢。接下来重点说一说多行文本溢出显示省略号,如下。实现方法:1234display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;overflow: hidden;适用范围:因使用了WebKit的CSS扩展属性,该方法适用于WebKit浏览器及移动端;注:• -webkit-line-clamp用来限制在一个块元素显示的文本的行数。 为了实现该效果,它需要组合其他的WebKit属性。常见结合属性:• display: -webkit-box; 必须结合的属性 ,将对象作为弹性伸缩盒子模型显示 。• -webkit-box-orient 必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式 。实现方法:1234567p{position: relative; line-height: 20px; max-height: 40px;overflow: hidden;}p::after{content: "..."; position: absolute; bottom: 0; right: 0; padding-left: 40px;background: -webkit-linear-gradient(left, transparent, #fff 55%);background: -o-linear-gradient(right, transparent, #fff 55%);background: -moz-linear-gradient(right, transparent, #fff 55%);background: linear-gradient(to right, transparent, #fff 55%);}适用范围:该方法适用范围广,但文字未超出行的情况下也会出现省略号,可结合js优化该方法。注:1. 将height设置为line-height的整数倍,防止超出的文字露出。2. 给p::after添加渐变背景可避免文字只显示一半。3. 由于ie6-7不显示content内容,所以要添加标签兼容ie6-7(如:<span>…<span/>);兼容ie8需要将::after替换成:after。以上所述是小编给大家介绍的css3溢出隐藏的方法
-
【功能模块】App开发【操作步骤&问题现象】1、LogInfoManagement App---->Page---->LogInfoManagement标准页面2、用户管理跟日志管理两个标准页面, 先访问用户管理页面, element-ui 这个css并没有加载, 然后访问日志管理页面, 其他的css文件一致没有重复加载,这就导致了element的css文件再最后加载了, 覆盖了之前自定义的样式我想知道 这个element的资源文件是在哪里引入的3、图1:样式错乱 图2:样式正常 图3:样式加载问题【截图信息】【日志信息】(可选,上传日志内容或者附件)
推荐直播
-
华为云码道-玩转OpenClaw,在线养虾2026/03/11 周三 19:00-21:00
刘昱,华为云高级工程师/谈心,华为云技术专家/李海仑,上海圭卓智能科技有限公司CEO
OpenClaw 火爆开发者圈,华为云码道最新推出 Skill ——开发者只需输入一句口令,即可部署一个功能完整的「小龙虾」智能体。直播带你玩转华为云码道,玩转OpenClaw
回顾中 -
华为云码道-AI时代应用开发利器2026/03/18 周三 19:00-20:00
童得力,华为云开发者生态运营总监/姚圣伟,华为云HCDE开发者专家
本次直播由华为专家带你实战应用开发,看华为云码道(CodeArts)代码智能体如何在AI时代让你的创意应用快速落地。更有华为云HCDE开发者专家带你用码道玩转JiuwenClaw,让小艺成为你的AI助理。
回顾中 -
Skill 构建 × 智能创作:基于华为云码道的 AI 内容生产提效方案2026/03/25 周三 19:00-20:00
余伟,华为云软件研发工程师/万邵业(万少),华为云HCDE开发者专家
本次直播带来两大实战:华为云码道 Skill-Creator 手把手搭建专属知识库 Skill;如何用码道提效 OpenClaw 小说文本,打造从大纲到成稿的 AI 原创小说全链路。技术干货 + OPC创作思路,一次讲透!
回顾中
热门标签