我最近买了一个马克杯,准备在工作时使用。作为一个专业的 Web 开发人员,我决定用它来彰显我办公室“反讽之王”的地位。当然,这个笑话并不独特,我在 T 恤、会议演示文稿等各种地方都见过它。

在座的各位中,大多数人可能都至少遇到过一次这个图片。这是一个我们都能感同身受的笑话,对吧?你尝试用 CSS 做一些简单的事情,但即使是基本属性之间相互作用的那些神秘方式,也会不可避免地搞砸它。
如果这个笑话体现了开发者对 CSS 的集体挫败感,那么冒着破坏乐趣的风险,我认为剖析其核心问题会很有趣,把它作为一个案例研究,来解释为什么人们会对 CSS 感到沮丧。
问题
查看 CodePen 上 Brandon (@brundolf) 编写的笔 CSS 真棒。
要出现此问题,必须满足三个条件
- 内容无法缩小以适应容器
- 容器无法扩展以适应内容
- 容器无法优雅地处理溢出
在现实场景中,第二个条件很可能是需要修复的问题,但我们将探讨所有三个条件。
修复内容大小
这对框的内容来说有点不公平,因为单词“AWESOME”在给定的字体大小和容器宽度下无法在一行内显示。默认情况下,文本在空格处换行,不会拆分单词。但让我们假设一下,我们绝对无法更改容器的大小。例如,文本可能是某个网站上放大的标题,而该网站正在非常小的手机上查看。
拆分单词
要使连续的单词换行,我们必须使用 CSS 属性 word-break
。将其设置为 break-all
将指示浏览器在必要时拆分单词,以便将文本内容换行到其容器内。
查看 CodePen 上 Brandon (@brundolf) 编写的笔 CSS 真棒:word-break。
其他内容
在这种情况下,使内容更具响应性的唯一方法是启用断字。但是,还有其他类型的可能溢出的内容。如果 word-wrap
设置为 nowrap
,则文本甚至不会在单词之间换行。或者,内容可能是块级元素,其 width
或 min-width
设置为大于容器的宽度。
修复容器大小
容器元素可能被强制不增长的方式有很多种。例如:width
、max-width
和 flex
。但它们都有一个共同点,那就是宽度是由内容以外的其他因素决定的。这本身并不坏,尤其是在没有固定高度的情况下,在这种情况下,内容通常会向下扩展。但是,如果您遇到此情况的变体,值得考虑您是否真的需要控制宽度,或者是否可以将其留给页面来确定。
width
的替代方案
设置 通常情况下,如果您设置了元素的 width
,并且以像素为单位设置,那么您实际上是想设置 min-width
或 max-width
。问问自己您真正关心的是什么。当该元素缺少内容时,它是否完全消失了,因为它缩小到宽度为 0?设置 min-width
,以便它具有尺寸,但仍然有空间增长。它是否变得太宽,以至于整段文字都放在一行上,难以阅读?设置 max-width
,以便它不会超过某个限制,也不会在小型设备上超出屏幕边缘。CSS 就像一个助手:您想要引导它,而不是指示它的每一个动作。
由 Flexbox 引起的溢出
如果您的某个 Flex 项目具有溢出的内容,事情就会变得稍微复杂一些。您可以做的第一件事是检查您是否指定了它的宽度,如上一节所述。如果您没有,那么可能发生的情况是该元素正在“Flex 缩小”。Flex 项目首先按照正常规则进行大小调整;width
、内容等。结果大小称为它们的 flex-basis
(也可以使用相同名称的属性显式设置)。在为每个项目建立 Flex 基线后,将应用 flex-grow
和 flex-shrink
(或 flex
,它一次指定两者)。项目以加权方式增长和缩小,基于这两个值和容器的大小。
设置 flex-shrink: 0
将指示浏览器此项目永远不应该小于其 Flex 基线。如果 Flex 基线由内容确定(默认值),则这应该可以解决您的问题。但是要小心,您可能会在元素的父级中再次遇到同样的问题。如果此 Flex 项目拒绝缩小,即使 Flex 容器小于它,它也会溢出,您又回到了原点。
处理溢出
有时根本无法避免。也许容器宽度受屏幕大小本身的限制。也许内容是数据表,其中行无法换行,列也无法进一步折叠。我们仍然可以比仅仅让它随意溢出更优雅地处理溢出。
overflow: hidden;
最简单的解决方案是隐藏溢出的内容。设置 overflow: hidden;
将简单地截断内容到达容器元素边框的位置。如果内容更具美学性质并且不包含关键信息,这可能是可以接受的。
查看 CodePen 上 Brandon (@brundolf) 编写的笔 CSS 真棒:overflow:hidden。
如果内容是文本,我们可以通过添加 text-overflow: ellipsis;
使其在视觉上更具吸引力,这会自动在被截断的文本中添加一个漂亮的“...” 。值得注意的是,您将看到更少的实际内容以腾出空间用于省略号。还要注意,这需要设置 overflow: hidden;
。
查看 CodePen 上 Brandon (@brundolf) 编写的笔 CSS 真棒:省略号。
overflow: auto;
通常,首选的解决方法是设置overflow-x: auto;
。这会让浏览器在内容溢出时添加滚动条,允许用户向该方向滚动容器。
查看CodePen上的Brandon (@brundolf) 编写的示例 CSS真棒:overflow:auto。
这是一个非常优雅的备选方案,因为它意味着无论如何,用户都能够访问所有内容。此外,滚动条只有在需要时才会出现,这意味着即使您不希望它发挥作用,在关键位置添加此属性也不是一个坏主意。
为什么这个难题会如此普遍地引起使用过 CSS 的人的共鸣?
CSS 很难,因为它的一些属性会相互影响,常常以意想不到的方式。因为当你设置其中一个属性时,你实际上并非只设置了那一件事。那一件事会与其他十几个因素结合、相互作用并发生冲突,包括你从未真正设置过的默认因素。
缓解此问题的一个经验法则是不要比必要时更明确。网页默认情况下是响应式的。编写良好的 CSS 意味着利用这一事实,而不是覆盖它。如果可能,使用百分比或视口单位代替媒体查询。在可以的情况下,使用min-width
代替width
。从规则的角度,从你真正想表达的意思的角度去思考,而不是只是添加属性直到事情看起来正确。尝试了解浏览器如何解决布局和大小调整,并在其基础上谨慎地进行更改和添加。与 CSS 合作,而不是对抗它。
另一个经验法则是让宽度或高度由内容决定。在本例中,这还不够,但在大多数情况下,它就足够了。给事物提供扩展的途径。当你设置元素大小规则时,特别是如果这些元素将包含文本内容,请仔细考虑极端情况。“如果此内容缩减为单个字符会怎样?如果此内容扩展为三个段落会怎样?它可能看起来不太好,但我的布局会完全破坏吗?”
CSS 很奇怪。它与任何其他代码都不一样,这使得很多程序员感到不舒服。但如果使用得当,它实际上可以非常棒。
必须链接到 John Alsop 的著名(且非常有先见之明)的文章“网页设计的道”:https://alistapart.com/article/dao
文章中的一段很棒的引言,与你的想法非常契合
“如果你正确地使用样式表,来暗示页面的外观,而不是控制页面的外观,并且你并不依赖样式表来传达信息,那么你的页面将在任何浏览器(过去或将来)中都能“正常”工作。”
拥抱固有的灵活性——不要与之对抗。:-)
从开发人员的角度来看,我100%同意。不幸的是,无论你多么努力地为此辩护,一些(我敢说,大多数)客户——甚至设计师和项目经理——对“在任何浏览器中都能正常工作”都有非常狭隘的看法。基本上,如果一个页面组件在每个浏览器中的外观不完全相同,那么它就不能正常工作,你就是一个不称职的开发人员(我是在转述)。也许我需要学习如何更好地劝说,但有时人们只是想花钱而花钱,所以我向他们收取费用。
收到那个马克杯后,我也做了一个笔 :) https://codepen.io/netsi1964/pen/QEVKzz
我也做了一个笔
查看Andy Parsons (@andparsons) 在CodePen上编写的示例 CSS真棒。
经典的“与之抗争,而不是对抗它”。一旦我深入研究了 HTML 和 CSS 规范,研究了每个元素的默认样式和属性,然后利用它来我的优势,我的开发生活变得轻松多了。
具有讽刺意味的是,Firefox 中的断字示例似乎坏了 :)
:P
我一直不讽刺地喜欢最初的图片,因为它完美地说明了 CSS 的强大功能。毕竟,尝试在单个元素中不使用 CSS 完成相同的事情。我唯一能想到的就是需要
img
或embed
,并且对于三个单词和一个框来说是糟糕的技巧。它们都会破坏在单个块中拖动选择文本的能力。我同意。
所有解决方案都是最小-有趣:25%;但最初的设计“应该”是什么样子?没人知道;)
我可能错了——这种情况时有发生——但这不是浏览器的错吗?为什么我们责怪 CSS 浏览器默认如何呈现内容?
我在本文中缺少一个重要的参考:我非常确定马克杯上的插图指的是 Internet Explorer。直到版本 6(由于预装在 Windows XP 中而拥有疯狂的 90% 市场份额的那个版本)它让网页开发者抓狂,因为它不允许马克杯所示的简单设置。
无论你对 CSS 做什么,IE 6 都会拉伸包含长单词(“AWESOME”)的框以使其适合,即使在其上设置了固定宽度。
那时,为浏览器兼容性而奋斗(“此页面针对 Netscape 版本 5+ 和 1024×768 px 的分辨率进行了优化。”)真是另一回事。
当它出现时,社区并没有这样理解——根据几个来源,是在 2009 年 3 月,所以我怀疑它指的是 IE6 和 Netscape 5——但我已经联系了创建者,询问他是否会过来解释背景。
有趣。虽然,我仍然坚持我之前所说,这不是 CSS 的错。所以,如果关于 IE 的评论属实,马克杯上不应该是“IE 很糟糕”吗?
@Eric:酷,我真的很想知道。
好吧,我的工作在 2009 年完全必须支持 IE 6,但我身处德国,遗憾的是,我们(关于 IE)的浏览器环境通常比美国落后几年。所以我在评估马克杯的起源时可能存在很大的偏见。
@James:我宁愿将其解读为“CSS 真棒[如果正确处理]”
大家好!我是史蒂夫,CSS 真棒设计的最初创建者。
Eric 询问我是否可以来讨论“CSS 真棒的背景和最初含义”。好吧,我希望它更有趣……
那是 2009 年,我花了似乎几个小时的时间试图在 CSS 中做一些事情,而我知道我可以用表格在几秒钟内完成。我非常努力地想用 CSS 来做,因为这就是你应该做的,但我对此不太擅长(剧透警告:我现在仍然不太擅长)。
我现在对溢出的概念有了稍稍更好的理解,但在当时,仅仅想到有人认为默认行为应该是让文本直接从框中伸出来,而不是像我漂亮的、合理的表格一直做的那样使框变大,这让我感到非常震惊。
无论如何,我只是那一刻充满了挫败感,并且,没有正确地解决问题,而是花了 5 分钟时间创建了一个讽刺的马克杯,然后又回到了使用表格。因为这是我在危急时刻的标志性举动。
这确实是全部内容。它并非针对特定的浏览器或个人或任何类似的东西。我认为可能有一些人会与这种体验产生共鸣并购买一个愚蠢的马克杯,但是,我的天哪,它传播的范围。
PS:我衷心希望我的愚蠢笑话没有冒犯到任何参与 CSS 发展多年的人。我确实很欣赏这个主题的复杂性,以及有人用建立在自己对某些东西缺乏理解基础上的廉价笑话来取乐是多么令人恼火。
啊。非常有趣的内容。不过我还是喜欢我自己的理解。:D
感谢分享!我确实喜欢 Florian 的解读,并且我坚持我讨厌浏览器的立场。它们在很多方面都达不成一致,这使得开发人员不得不求助于诸如 autoprefixer、同一资源的多种文件类型、SVG hacks、polyfills 和令人困惑的马克杯等手段。 :)
哇,我绝对没想到会收到马克杯最初的创作者的评论。受宠若惊 :)
公平地说,我敢打赌 2009 年的 CSS 实际上并没有那么棒。我自己直到 2012 年才开始使用它,所以我不了解第一手情况,但即使在 2012 年,像浮动黑客这样的东西仍然是常见的做法。
无论如何,非常感谢您提供的额外背景信息,并感谢您提供的这款很棒的马克杯!
不过缺少了一种替代方案:连字符换行。与溢出操作相比,它可能更优雅地解决“超出盒子”的问题。
再见,w0lf。
我完全同意!这就是我喜欢 CSS 的原因。
除了省略号之外,所有解决方案在 Firefox 移动版上都失败了。CSS 并不棒。继续努力吧。
如果您能控制 Html,则可以使用可选的连字符标记 () 使第一种情况更美观一些。
详情:https://css-tricks.cn/almanac/properties/h/hyphenate/
由于相关案例假设内容和容器不在其正常(理想)状态,无论是由于屏幕尺寸还是其他因素,我们都不希望在标记本身中添加连字符。但是,您指出了 CSS 的
hyphens
属性是正确的,我之前并不知道。第一个(word-break)解决方案绝对可以从hyphens: auto
中受益。我认为马克杯 2.0 已经准备好发货了!
有趣的是,我从未将这张图片视为
“你尝试用 CSS 做一些简单的事情,即使是基本属性的交互方式也会不可避免地导致它出错”
我一直将这张图片解读为更具象征意义的东西。这意味着 CSS 非常强大,它打破了模式,并允许开发人员在设计中跳出框框思考。
但现在我完全理解你的意思了,你让我大开眼界了 :)
抱歉,如果这显得过于吹毛求疵,但在“修复内容大小”标题下的段落中,你写道“但让我们假设一下,我们绝对负担不起更改容器大小的成本”。
这句话应该将“大小”一词替换为“宽度”,因为您在解决方案中增加了容器的高度。
鉴于约束条件,我假设您会调整字体大小。
我(像许多人一样)曾经在关于调试 CSS的演示文稿中使用过这个。最终我修复了错误,直到我得到一个纯 CSS 镜面球。
试试用表格做这个;P
我喜欢我们有一个如此受欢迎的、普遍的 CSS 挫败感的象征。我们都经历过。
我有一个使用 SVG 的答案,但你不会喜欢的。
好主意,但它在 Microsoft Edge 上不起作用!
我之前真的从未在其他任何地方见过这个马克杯,现在我的心因为阅读这篇文章而变得无比激动,谢谢您 :)
我的第一位导师拥有这个马克杯,并在她离开我们公司时送给了我,从那以后我一直珍藏它(7 年和 3 份工作)——它是我上一份工作时的办公室啤酒杯,现在是我当前工作时的日常苏打水杯。
然后,两个月前,我在我们办公室的厨房里把它摔碎了。我把它给了我哥哥,因为他是一个超级胶水大师。如果他不能让它恢复到饮料容器的状态,我想我会把它当作一个小花盆,这样我仍然可以把它放在我的桌子上。我知道我可以买一个新的,但这当然不是重点 :)
无论如何,谢谢您!!干杯,
Alison
哦,你的 CSS(马克杯)坏了,真是讽刺。很抱歉听到这个消息,但它可能仍然在 Chrome 中运行。
哈哈@Kel,说得对 :)
CSS 太棒了,为什么要使用 HTML;P
来自 Christian Kaindl,在比赛结束之后
主题