- 原文地址:Common CSS Issues For Front-End Projects
- 原文做者:Ahmad Shadeed
- 译者:Chor
快速摘要:近年来,跨浏览器的渲染和交互已经越发一致。不过,它仍然没有达到彻底一致,有不少小问题会让你出错。除了这些问题以外,还有不一样的屏幕尺寸、语言偏好和明显的人为错误等不肯定因素,咱们从中发现了许多会让开发者出错的小问题。css
在浏览器中实现用户界面时,最好是尽量地减少这些差别和问题,以便 UI 呈现出预测的样子。记住全部的这些差别是很困难的,因此我列举了一系列常见问题以及解决方案。当你在作一个新项目的时候,能够将其做为一份方便的参考指南。 html
咱们开始吧。前端
button
和 input
元素的背景添加按钮时,重置它的背景,不然在跨浏览器时它的呈现会有所不一样。下面的例子分别展现了 Chrome 和 Safari 中的同一个按钮,后者默认会有一个灰色背景。git
(大图预览)github
重置背景能够解决这个问题:web
button { appearance: none; background: transparent; /* 其它样式 */ }
https://codepen.io/shadeed/pe...浏览器
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代码 按钮和输入框。app
scroll
和 auto
为了限制一个元素的高度并容许用户在其中滚动,添加 overflow: scroll-y
。在 macOS 下的 Chrome 中,这看起来不错,可是在 Windows 下的 Chrome 中,滚动条始终存在(即便内容很短)。这是由于 scroll-y
会无视内容,一直显示滚动条。而 overflow: auto
只在须要的时候才会显示滚动条。less
左边:macOS 下的 Chrome。右边:Windows 下的 Chrome (大图预览)dom
.element { height: 300px; overflow-y: auto; }
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代码 overflow-y。
flex-wrap
要想让一个元素表现得像弹性容器那样,只需添加 display: flex
。可是,若是没有添加 flex-wrap
,那么当屏幕尺寸缩小的时候,将会出现水平滚动条。
<div class="wrapper"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div>
.wrapper { display: flex; } .item { flex: 0 0 120px; height: 100px; }
上面的例子在大屏幕下表现正常。在移动端下,浏览器将会出现水平滚动条。
左边:出现水平滚动条,而且项目没有换行。右边:项目换行,呈两行显示 (大图预览)
解决方法很简单。wrapper 应该在空间不足时让项目换行。
.wrapper { display: flex; flex-wrap: wrap; }
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代码 overflow-y。
justify-content: space-between
对一个弹性容器应用 justify-content: space-between
时,它会为元素分配空间,使它们互相之间的距离相等。咱们的例子中有 8 个卡片项目,看起来没什么问题。若是因为某种缘由,项目的数量是 7 呢?第二行的元素看起来将会与第一行的不一样。
包含 8 个项目的 wrapper (大图预览)
包含 7 个项目的 wrapper(大图预览)
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代码 overflow-y。
在这种状况下,使用 CSS 网格将会更加合适。
在手机屏幕上浏览文章的时候,一个长词或者内联连接可能会致使页面出现水平滚动条。使用 CSS 的 word-break
能够防止这个问题。
(大图预览)
.article-content p { word-break: break-all; }
(大图预览)
当使用透明起点和终点添加渐变的时候,在 Safari 下会呈现一片漆黑。这是由于 Safari 没法识别关键字 transparent
。经过使用 rgba(0, 0, 0, 0)
来替代它,咱们能够达到预期的效果。注意下面的截图:
顶部: Chrome 70。底部:Safari 12 (大图预览)
.section-hero { background: linear-gradient(transparent, #d7e0ef), #527ee0; /* 其它样式 */ }
应该替换为:
.section-hero { background: linear-gradient(rgba(0, 0, 0,0), #d7e0ef), #527ee0; /* 其它样式 */ }
auto-fit
和 auto-fill
差别的误解在 CSS 网格布局中,repeat
函数能够在不使用媒体查询的状况下建立响应式列布局。为此,可使用 auto-fill
或者 auto-fit
。
.wrapper { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); }
(大图预览)
简而言之,auto-fill
将会在不扩展列宽度的状况下对它们进行排列,而auto-fit
则会在存在空列的时候使其宽度塌陷为 0。Sara Soueidan 写了一篇不错的文章讨论过这个问题。
若是你在视窗不够高的时候将一个元素固定在屏幕顶部,会发生什么事呢?很简单:它将占用屏幕空间,最终致使可供用户浏览网站的垂直区域变得很小、很不舒服,影响他们的体验。
@media (min-height: 500px) { .site-header { position: sticky; top: 0; /* 其它样式 */ } }
上面的代码中,咱们让浏览器只在视窗高度等于或大于 500 像素的时候才固定顶部。
还有一点很重要:使用 position: sticky
的时候,除非指定 top
属性,不然它不会生效。
(大图预览)
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代码 overflow-y。
max-width
添加图片时,定义 max-width: 100%
,这样图片会在屏幕较小的时候改变大小。不然浏览器将会显示水平滚动条。
img { max-width: 100%; }
main
和 aside
元素CSS 网格可用于定义布局中的 main
部分和 aside
部分,这是 CSS 网格的绝佳用途。问题是,即便 aside
是空的,它的高度也会和 main
的高度相等。
要修复这个问题,可让 aside
元素与其父元素的起点对齐,这样它的高度就不会扩展了。
.wrapper { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-gap: 20px; } // align-self 将会让 aside 元素与其父元素的起点对齐。 aside { grid-column: 1 / 4; grid-row: 1; align-self: start; } main { grid-column: 4 / 13; }
(大图预览)
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代码 overflow-y。
fill
使用 SVG 时,若是在 SVG 内部添加 fill
,有时候它可能不会如预期的那样生效。要修复这个问题,要么移除 SVG 自身的 fill
属性,要么覆盖 fill: color
。
举个例子:
.some-icon { fill: #137cbf; }
若是 SVG 有一个内联 fill 的话,这段代码将不会生效。应该替换为:
.some-icon path { fill: #137cbf; }
不管什么时候,我都很喜欢使用伪元素。伪元素为咱们提供了一种建立假元素的方法,主要用来装饰,同时又无需将其添加到 HTML 中。
使用它们的时候,开发者可能会忘记作下面的事情:
content: ""
属性,display
属性的状况下设置它们的 width
和 height
下面的例子中,咱们有一个标题,其标记是一个伪元素。必须给元素添加 content: ""
属性,同时还要为它设置 display: inline-block
,以使 width
和 height
像预期的那样生效。
(大图预览)
display: inline-block
时奇怪的空隙给两个或两个以上的元素设置 display: inline-block
或者 display: inline
,将会致使它们之间产生一个微小的空隙。缘由是浏览器会将元素看成字词去解释,从而给每一个元素之间添加一个字符的空隙。
下面的例子中,每一个项目的右侧都有一个 8px
的空隙,可是使用 display: inline-block
而产生的小空隙将会使其变为 12px
,这不是咱们想要的效果。
li:not(:last-child) { margin-right: 8px; }
(大图预览)
经过给父元素设置 font-size: 0
能够简单地解决这个问题。
ul { font-size: 0; } li { font-size: 16px; /* 应该在这里从新设置字体大小,由于它会从父元素继承 `font-size: 0`。*/ }
(大图预览)
https://codepen.io/shadeed/pe...
查看 Ahmad Shadeed(@shadeed)在 Codepen 上的代码 overflow-y。
for="ID"
使用表单元素时,确保全部的 label
元素都分配到了一个 ID。这将提升它们的可访问性,点击的时候,相关的输入框将得到焦点。
<label for="emailAddress">Email address:</label> <input type="email" id="emailAddress">
(大图预览)
给整个文档设置字体的时候,字体并不会应用于诸如 input
, button
select
和 textarea
这些元素上。默认状况下,它们并不会继承文档字体,由于浏览器给它们应用了系统字体。
要修复这个问题,直接设置字体属性:
input, button, select, textarea { font-family: your-awesome-font-name; }
有些元素的宽度可能会致使出现一个水平滚动条。
要找到问题的根源,最简单的方法就是使用 CSS outline。Addy Osmani 写了一个方便的脚本 。将其添加到浏览器的控制台,页面上全部元素的轮廓都会显示出来。
[].forEach.call($$("*"), function(a) { a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16); });
(大图预览)
用 CSS 调整一张图片的大小时,若是纵横比与图片的宽高不一致,则图片会被压缩或拉伸。
解决方法很简单:使用 CSS 的 object-fit
。它的功能和给背景图片设置 background-size: cover
相似。
img { object-fit: cover; }
(大图预览)
object-fit
并不是百试百灵。一些图片必须在不裁剪或者不调整大小的状况下显示,而且某些平台会强制用户以特定的尺寸裁剪或上传图片。例如,Dribbble 规定上传的缩略图尺寸为 800 x 600 像素。
input
添加正确的 type
为 input
使用正确的 type
。这将改善移动端的用户体验,并使用户更容易访问。
这是部分 HTML:
<form action=""> <p> <label for="name">Full name</label> <input type="text" id="name"> </p> <p> <label for="email">Email</label> <input type="email" id="email"> </p> <p> <label for="phone">Phone</label> <input type="tel" id="phone"> </p> </form>
每一个输入框分别获取焦点时,看起来是这样的:
(大图预览)
在一个从右到左的布局中添加诸如 + 972-123555777
的手机号码时,加号将会位于号码末尾。要修复这个问题,能够从新指定手机号码的方向。
p { direction: ltr; }
(大图预览)
这里提到的全部问题都是我在前端开发工做中最常遇到的。个人目标是在开发 web 项目时按期检查这份清单。
你在 CSS 中有没有常常遇到什么问题呢?欢迎在评论区分享!