likes
comments
collection
share

🦄CSS Magic-踩坑及解决思路🦄

作者站长头像
站长
· 阅读数 12

作为开放WEB核心语言之一,css从一开始就给开发者带来无限惊喜,你可以使用它来实现最基础的样式到各种炫酷的页面效果。

当然有时候带来的会是惊吓,尤其当你碰到一个看似无厘头无解的问题,调整半天也无法解决问题时,你可能会思索,为什么CSS会是这样一个简单又复杂的语言。每个人都会遇到过这样的场景。

文章接下来就带大家了解几个在开发中使用到的新特性和遇到的诡异表现,希望你能有所收获。

图片水平垂直居中

有一天,产品找来说,现有图片被截取了,能不能做到垂直居中并且图片不变形不截取的效果。

作为多年的开发者,直觉告诉我“这个完不成,不可能做的”,但是具有职业素质的我不会这样回答的,所以回答道“等等我研究下。。。”(研究完可能就做不了吧)。

不过凭着对技术工作的爱好,经过不断的研究学习(主要就是百度谷歌),发现问题可以解决。

代码如下:

<style>
  li {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  li image {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
  }
</style>
<ul>
  <li><image src="" /></li>
  <li><image src="" /></li>
</ul>

这里关键是的对image宽高、最大宽高的设定,让图片最终能在容器水平、垂直居中。

当然也有其他方案,grid或者使用古老table也能实现同样的效果。

border-radius无圆角效果

你应该跟我一样,看到这个标题会觉得不可思议,border-radius本身不就是为了实现圆角效果,这标题肯定是故弄玄虚。

是的,你是对的,这个问题确实不可能发生,因为需要一些额外条件,比如:需要是IOS设备,并且应用了动画。比如:

图片3

<style>
  .container {
    width: 300px;
    height: 300px;
    background-color: gray;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: 100px;
  }
  .buggy {
    width: 300px;
    height: 300px;
    animation: 2s linear infinite;
    animation-name: ani;
    background-color: blanchedalmond;
  }
  @keyframes ani {
    0% {
      transform: translateX(0);
    }
    100% {
      transform: translateX(300px);
    }
  }
</style>
<div class="container">
  <div class="buggy"></div>
</div>

上述代码即可在IOS设备上复现bug,.container不能使用overflow: hidden;来隐藏其内部元素的超出内容,因为.buggy带有动画。

解决方法就是给.containertransform: translate(0);类似transform的方法,都能解决同样场景的圆角问题。

我一开始听UI验收时说这个地方没有圆角的时候,很迷茫,因为当时觉得这是不可能的事,所以说经验也会误导人,实践才能出真知。

:has & :not

:has

:has是CSS4规范中提出的伪类选择器,表示如果传递进去的选择器参数至少匹配一个元素,即匹配改元素

比如a:has(> img)匹配所有直接包含img标签的a标签元素

它可以增加css更多的可能性,而且它还可以匹配兄弟元素的规则,比如a:has(+ b)表示选择所有下一个元素是b的a标签

<style>
  .card:has(img) {}
  .card > div:has(h2) {}
  .card > div:has(span) {}
</style>
<div class="card">
  <img src="" alt="" />  <!-- 可能不存在 -->   <div>
    <h2></h2>  <!-- title -->     <span></span>  <!-- subtitle -->   </div>
</div>

在做一个包含文案和图片的介绍卡片,即可以通过:has来设计多套css,比如没有图片的卡片如何渲染,文案包含多层级如何渲染,这在之前的话只能直接用类名来表达。

了解更多使用场景

:not

:not也是CSS4规范中提出的伪类选择器,表示不匹配传递进去的选择器列表的元素

span:not(.active)匹配所有类名不包含active的span元素

从我个人经验来看,它会让CSS应用的规则更精准,而不是同一个元素带有多个同属性CSS样式

<style>
.tab { width: 50%; font-weight: normal; }
.tab:not(.active) { font-weight: normal; }
.tab.active { font-weight: bold; }
</style>
<div>
  <div class="tab active"></div>
  <div class="tab"></div>
</div>

比如开发一个TAB,每个tab都会有激活态和非激活态,当激活态的时候字体需要加粗,这个时候.tab.active同样会应用一个粗体样式覆盖.tab

但是使用:not就会使font-weight: normal在激活态的时候并不会生效

注意

它不能嵌套使用,:not(:not())是无效的

会把选择器权重(specificity)提高到最高,span:not(#id)中specificity为id级,而不是标签级别

只会应用到一个元素而不能排除所有祖先元素,body :not(table) a会只应用到table里的a标签,但是td里的a标签不会应用:not的规则(即在选择器匹配范围内)

总结

以上是对:has``:not的一个简单介绍,如果感兴趣的话可以更深入了解规范:has:not

当然它们的使用场景远比我提出的例子多,希望能在了解完它们之后能有灵感来设计出更好的效果和CSS代码结构。

@layer

一个比较新的主题,CSS at-rule @layer,它可以用来生成一个新层,也可以在多层中定义优先次序。

它的意义在于避免CSS冲突,可以把规则放到各自的layer层,而且更安全的写第三方CSS或者引入第三方CSS,不用担心CSS重叠、冲突、specificity等问题。

不过现有的兼容性比较一般,而且其本身设计是作为整个CSS架构的根本构建模块,所以很难有手动兼容方式来实现同样的效果。兼容可能会包含大块重复代码,用不同选择器来管理层叠样式。

参考内容

Cascading & Inheritance Level 5 Specification

MDN Documentation @layer

in-depth review of cascade layers

CSS Variable

来到最后一个主题,CSS Variable新但又不算太新的概念,5年前就已经有浏览器实施了规范,

不过至今在开发中的使用率仍比较低,比较多见于前端框架中。

它是由开发者定义的包含特定值的实体,在文档内可重用,通过var()来使用提前定义好的变量值。

:root {
  --primary-color: blue;
}
div {
  color: var(--primary-color);
}

它的意义在于从规范上减少重复的CSS值,比如颜色,标准字体、间距、宽高等等。

之前实施的话基本要靠sass、less等css扩展语言来实现,但是现在有了CSS变量,开发者完全可以用CSS规范来实施同样的一套变量,更便捷地统一规范,减少大量重复代码。

总结

文章简要介绍了几个开发中遇到的疑难杂症,和几个比较新奇的CSS新特性,希望能在帮助大家解决部分问题的同时,增加对新特性的了解和好奇心,在对CSS不断学习中使用CSS新特性设计出更好的交互,更好地维护代码。

有bug?想补充?

感谢大家观看这篇文章,有任何问题或想和我交流,请直接留言,

发现文章有不妥之处,也可指出交流,感谢阅读~

🦄CSS Magic-踩坑及解决思路🦄