「译」前端项目中常见的 CSS 问题
source link: https://www.tuicool.com/articles/J7RjuuJ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
- 原文地址: Common CSS Issues For Front-End Projects
- 原文作者:Ahmad Shadeed
快速摘要:近年来,跨浏览器的渲染和交互已经愈加一致。不过,它仍然没有达到完全一致,有很多小问题会让你出错。除了这些问题之外,还有不同的屏幕尺寸、语言偏好和明显的人为错误等不确定因素,我们从中发现了许多会让开发者出错的小问题。
在浏览器中实现用户界面时,最好是尽可能地减小这些差异和问题,以便 UI 呈现出预测的样子。记住所有的这些差异是很困难的,所以我列举了一系列常见问题以及解决方案。当你在做一个新项目的时候,可以将其作为一份方便的参考指南。
我们开始吧。
1. 重置 button
和 input
元素的背景
添加按钮时,重置它的背景,否则在跨浏览器时它的呈现会有所不同。下面的例子分别展示了 Chrome 和 Safari 中的同一个按钮,后者默认会有一个灰色背景。
重置背景可以解决这个问题:
button { appearance: none; background: transparent; /* 其它样式 */ }
2. Overflow: scroll
和 auto
为了限制一个元素的高度并允许用户在其中滚动,添加 overflow: scroll-y
。在 macOS 下的 Chrome 中,这看起来不错,但是在 Windows 下的 Chrome 中,滚动条始终存在(即使内容很短)。这是因为 scroll-y
会无视内容,一直显示滚动条。而 overflow: auto
只在需要的时候才会显示滚动条。
.element { height: 300px; overflow-y: auto; }
3. 添加 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; }
4. 当弹性项目数量不定时,不要使用 justify-content: space-between
对一个弹性容器应用 justify-content: space-between
时,它会为元素分配空间,使它们互相之间的距离相等。我们的例子中有 8 个卡片项目,看起来没什么问题。如果由于某种原因,项目的数量是 7 呢?第二行的元素看起来将会与第一行的不同。
在这种情况下,使用 CSS 网格将会更加合适。
5. 长词和链接
在手机屏幕上浏览文章的时候,一个长词或者内联链接可能会导致页面出现水平滚动条。使用 CSS 的 word-break
可以防止这个问题。
.article-content p { word-break: break-all; }
6. 透明渐变
当使用透明起点和终点添加渐变的时候,在 Safari 下会呈现一片漆黑。这是因为 Safari 无法识别关键字 transparent
。通过使用 rgba(0, 0, 0, 0)
来替代它,我们可以达到预期的效果。注意下面的截图:
.section-hero { background: linear-gradient(transparent, #d7e0ef), #527ee0; /* 其它样式 */ }
应该替换为:
.section-hero { background: linear-gradient(rgba(0, 0, 0,0), #d7e0ef), #527ee0; /* 其它样式 */ }
7. CSS 网格布局中关于 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 写了一篇 不错的文章
讨论过这个问题。
8. 当视窗高度不足时将元素固定在屏幕顶部
如果你在视窗不够高的时候将一个元素固定在屏幕顶部,会发生什么事呢?很简单:它将占用屏幕空间,最终导致可供用户浏览网站的垂直区域变得很小、很不舒服,影响他们的体验。
@media (min-height: 500px) { .site-header { position: sticky; top: 0; /* 其它样式 */ } }
上面的代码中,我们让浏览器只在视窗高度等于或大于 500 像素的时候才固定顶部。
还有一点很重要:使用 position: sticky
的时候,除非指定 top
属性,否则它不会生效。
9. 为图片设置 max-width
添加图片时,定义 max-width: 100%
,这样图片会在屏幕较小的时候改变大小。否则浏览器将会显示水平滚动条。
img { max-width: 100%; }
10. 使用 CSS 网格定义 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; }
11. 给一个 SVG 添加 fill
使用 SVG 时,如果在 SVG 内部添加 fill
,有时候它可能不会如预期的那样生效。要修复这个问题,要么移除 SVG 自身的 fill
属性,要么覆盖 fill: color
。
举个例子:
.some-icon { fill: #137cbf; }
如果 SVG 有一个内联 fill 的话,这段代码将不会生效。应该替换为:
.some-icon path { fill: #137cbf; }
12. 使用伪元素
无论何时,我都很喜欢使用伪元素。伪元素为我们提供了一种创建假元素的方法,主要用来装饰,同时又无需将其添加到 HTML 中。
使用它们的时候,开发者可能会忘记做下面的事情:
-
添加
content: ""
属性, -
在没有定义
display
属性的情况下设置它们的width
和height
下面的例子中,我们有一个标题,其标记是一个伪元素。必须给元素添加 content: ""
属性,同时还要为它设置 display: inline-block
,以使 width
和 height
像预期的那样生效。
13. 使用 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`。*/ }
14. 分配一个标签元素给一个输入框时,添加 for="ID"
使用表单元素时,确保所有的 label
元素都分配到了一个 ID。这将提高它们的可访问性,点击的时候,相关的输入框将获得焦点。
<label for="emailAddress">Email address:</label> <input type="email" id="emailAddress">
15. 交互式 HTML 元素的字体不生效
给整个文档设置字体的时候,字体并不会应用于诸如 input
, button
select
和 textarea
这些元素上。默认情况下,它们并不会继承文档字体,因为浏览器给它们应用了系统字体。
要修复这个问题,直接设置字体属性:
input, button, select, textarea { font-family: your-awesome-font-name; }
16. 水平滚动条
有些元素的宽度可能会导致出现一个水平滚动条。
要找到问题的根源,最简单的方法就是使用 CSS outline。Addy Osmani 写了一个方便的 脚本 。将其添加到浏览器的控制台,页面上所有元素的轮廓都会显示出来。
[].forEach.call($$("*"), function(a) { a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16); });
17. 压缩或拉伸图片
用 CSS 调整一张图片的大小时,如果纵横比与图片的宽高不一致,则图片会被压缩或拉伸。
解决方法很简单:使用 CSS 的 object-fit
。它的功能和给背景图片设置 background-size: cover
类似。
img { object-fit: cover; }
object-fit
并非百试百灵。一些图片必须在不裁剪或者不调整大小的情况下显示,并且某些平台会强制用户以特定的尺寸裁剪或上传图片。例如,Dribbble 规定上传的缩略图尺寸为 800 x 600 像素。
18. 为 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>
每个输入框分别获取焦点时,看起来是这样的:
19. RTL 布局中的手机号码
在一个从右到左的布局中添加诸如 + 972-123555777
的手机号码时,加号将会位于号码末尾。要修复这个问题,可以重新指定手机号码的方向。
p { direction: ltr; }
结论
这里提到的所有问题都是我在前端开发工作中最常遇到的。我的目标是在开发 web 项目时定期检查这份清单。
你在 CSS 中有没有经常遇到什么问题呢?欢迎在评论区分享!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK