CSS容器查询和悬浮间隙问题
容器查询和悬浮间隙问题1. 容器查询在开发一个现代网页时例如一个卡片组件。当它摆在页面正中央时横向排版。然而当把同一个组件复用到窄的侧边栏时整个画面会挤压变形。过去为了解决这个问题我们只能配合全局的媒体查询去套不同的父级类名media(min-width:1024px){/* 放到主内容区横着排 */.main-content .my-card{flex-direction:row;}/* 放到侧边栏竖着排 */.sidebar .my-card{flex-direction:column;}}这种做法不仅打破了组件的封装性必须关注屏幕视口大小还让代码变得极难维护。媒体查询 和 容器查询媒体查询 组件根据浏览器视口有多宽来决定自己的形态。容器查询 组件根据父级容器有多大来决定自己的形态。这意味着组件不再关心它被放在了哪里它只关心分给自己的空间有多少。如何开启容器查询以下面的代码为例第一步HTML 结构首先我们在页面里创造两个容器一个窄模拟侧边栏一个宽模拟主内容区里面放的组件 HTML 代码完全一模一样。divclasspage-layoutdivclasssidebar-containerdivclassweather-widgetdivclassweather-status☀️/divdivclassweather-infoh3北京/h3p晴间多云 · 26°C/pspanclasstips适合户外运动/span/div/div/divdivclassmain-containerdivclassweather-widgetdivclassweather-status☀️/divdivclassweather-infoh3北京/h3p晴间多云 · 26°C/pspanclasstips适合户外运动/span/div/div/div/div第二步在 CSS 中声明谁是容器要想让天气组件能够识别父级大小我们必须先让浏览器看这两个包裹层的宽度变化/* 让两个容器一个窄一个宽 */.sidebar-container{width:300px;}.main-container{width:800px;}/* 将其定义为一个“宽度监听容器” */.sidebar-container, .main-container{container-type:inline-size;}注container-type: inline-size;意思是让浏览器只监听该容器的水平宽度变化只有宽度变化才能触发容器查询。因为网页布局绝大多数都在纵向滚动宽度才是决定组件是该横排还是竖排的关键。第三步用container编写自适应样式现在开始编写天气组件自己的样式。我们先写出它在窄空间下的默认状态垂直排列然后用container写它在大空间下的横向排列。/* 1. 默认状态窄容器/侧边栏垂直布局像个普通的列表项 */.weather-widget{display:flex;flex-direction:column;/*主轴设为垂直方向*/align-items:center;padding:15px;background:#f0f8ff;border-radius:12px;text-align:center;}.weather-status{font-size:40px;}.tips{display:none;}/* 窄的时候空间不够把温馨提示隐藏掉 *//* 2. 当这个组件所在的“父容器”宽度大于 500px 时横向排列 */container(min-width:500px){.weather-widget{flex-direction:row;justify-content:space-around;padding:30px;background:linear-gradient(135deg,#e0f2fe,#bae6fd);text-align:left;}.weather-status{font-size:80px;}.tips{display:inline-block;margin-top:8px;color:#0369a1;}}动态改变的一个样例!DOCTYPEhtmlhtmllangzh-CNheadmetacharsetUTF-8metanameviewportcontentwidthdevice-width, initial-scale1.0titleDocument/titlestyle*, *::before, *::after{box-sizing:border-box;}html, body{display:flex;flex-direction:column;justify-content:flex-start;align-items:center;background-color:#ffc048;color:#1e272e;}img{display:block;border:0 none;width:100%;max-width:100%;height:auto;margin:0;}main{display:flex;flex-direction:column;justify-content:flex-start;width:100vw;max-width:1400px;margin:0 auto;padding:1rem;}.main-content{width:100%;margin:1rem 0 0 0;}.card{background:#fff;padding:1rem;border:1px solid #1e272e;box-shadow:5px 5px 0px #1e272e;/* 容器查询 */container-type:inline-size;container-name:card;resize:both;overflow:scroll;}.card .content{display:flex;flex-direction:column;justify-content:flex-start;}p{font-size:1rem;line-height:1.5;margin:1rem 0 0 0;}.card .copy p:first-child{font-size:1.25rem;}media(min-width:600px){main{flex-direction:row;}.main-content{width:calc(100% - 400px);margin:0 0 0 0.5rem;}}containercard(min-width:600px){.card .content{flex-direction:row;}.card img{align-self:flex-start;width:50%;max-width:400px;}.card .copy{margin:0 0 0 1rem;}.card .copy p{font-size:1.125rem;}.card .copy p:first-child{font-size:1.75rem;margin:0;}}/style/headbodymaindivclassmain-contentdivclasscarddivclasscontentimgsrc./IMG_8945.JPGaltdivclasscopypstrong容器查询/strong/ppCSS 容器查询允许开发者根据容器元素自身的尺寸来调整子元素的样式而不再仅仅依赖视口宽度。这使得组件在不同布局上下文中都能保持优雅的响应式表现。/pp调整卡片大小当容器宽度超过 600px 时图片和文字会自动切换为水平排列字号也会相应增大。这就是容器查询带来的组件级响应能力。/p/div/div/div/div/main/body/html使用resize: both;配合overflow: scroll;实现调整容器大小。container-name: card;给开启容器查询的盒子命名精准匹配提高可读性也更易于维护不加名字的话是自动检测上一个开启了容器查询的父盒子。container card (min-width: 600px)后面用容器查询的时候加上名字。2. 悬浮间隙问题在写百度页面时需要实现鼠标悬停在某个按钮上然后出现下拉菜单或是说明但是在鼠标从按钮移动到悬浮窗的过程中鼠标会经过一个空白区域导致悬浮窗消失。解决方法这个功能有多个html结构都可以实现按钮元素作为父亲包含下拉菜单元素。divclassbuttondivclassfloat菜单/div/div按钮和下拉菜单为兄弟元素。divclassbutton/divdivclassfloat菜单/div有一个包裹盒。divclasscontainerdivclassbutton/divdivclassfloat菜单/div/div.container{position:relative;}.float{visibility:hidden;position:absolute;left:55px;top:55px;}.container:hover .float{visibility:visible;}以第三种结构为例1. 缩小间隙向上移动float盒子让其紧贴着包裹盒 也就是container。.float{margin-top:-10px;padding-top:10px;}2. 伪元素补位在菜单和按钮的空隙处定位一个菜单的伪元素再加opacity: 0; / background color: transparent;将其隐藏。但是在这里不能加display: none; / visibility: hidden;这两个属性无法被 hover。属性是否占位能否被 hoverdisplay: none不存在不能visibility: hidden占位不能opacity: 0占位能background color: transparent;占位能.float::before{position:absolute;top:-10px;height:10px;width:100%;opacity:0;}3. 延迟消失给菜单的消失添加延迟注意这里显示和隐藏的延迟要分开写显示是0s隐藏才加延迟。.float{visibility:hidden;transition:visibility 0s .2s;}.container:hover .float{transition:visibility 0s 0s;visibility:visible;}4. clip-path用 clip-path pointer-events 让包裹盒的实际 hover 区域比视觉更大。比较少用。