这是关于如何在 Internet Explorer (IE) 中使用 CSS grid 的三部分系列文章的第一篇。想象一下编写 CSS grid 代码而无需编写回退布局!我们中的许多人认为,这只是一个遥远的未来,还需要很多年才能实现。如果唯一阻止你实现这一目标的是 IE11(查看 caniuse.com),那么你很幸运!这一天已经到来了!或者至少在你看完本系列文章后就会到来。😉
系列文章
- 打破常见的 IE Grid 误解(本篇文章)
- CSS Grid 和新的 Autoprefixer
- 使用间隙模拟自动放置网格
- 重复区域名称现在已受支持!
首先,这第一部分将揭穿围绕 IE11 本机网格实现的一些常见误解。
在第二部分中,我将揭开使用 IE11 中的 CSS grid 非常难的这个神话。IE11 不再需要糟糕的回退布局!
在第三部分中,我将向您展示我用来创建简单自动放置网格的酷炫 flexbox 技术。这些假自动放置网格具有固定像素的网格间隙,与使用真实 CSS grid 创建的网格间隙完美对齐。它们在 IE11 中完美运行,完全响应,并且根据屏幕宽度更新其列数只需要更改媒体查询中的一个宽度值。
介绍到此为止,让我们开始了解这些误解吧!
IE确实具有隐式网格
在 CSS grid 中,显式网格是您使用所有 grid-template-*
属性手动定义的网格。隐式网格是浏览器处理放置在显式网格外部的单元格的方式。
在现代浏览器中使用 CSS grid 时,隐式网格非常明显,因为网格将继续在新的行上自动创建和放置网格单元格,而无需定义它们。IE 不支持自动放置,因此很容易假设 IE 没有隐式网格。但实际上它有——您只需要在使用它时更明确一些。
查看 CodePen 显式与隐式网格,作者是 Daniel Tonon (@daniel-tonon),发布在 CodePen 上。
使用 IE 隐式网格最常见的用例是使用它为您生成行。如果您希望网格中的所有行的高度都由其内容的高度决定,则不需要费心定义 -ms-grid-rows
(IE 版本的 grid-template-rows
)。在放置网格单元格时,IE 会自动为您生成行。
需要注意的重要一点是,现代浏览器可以访问 grid-auto-rows
和 grid-auto-columns
属性。这些属性允许您控制浏览器如何处理隐式网格中行和列的大小。IE 不了解这些属性。IE 的隐式行和列只能始终以 auto
大小存在。
IE 具有 repeat 功能
不要害怕!您无需为您的 12 列网格编写 12 次 1fr 20px
(IE 不支持本机网格间隙)。IE 预先打包了完整的 repeat()
功能。它只是隐藏在不同的语法后面。
在列和行中重复值的现代语法是 repeat(12, 1fr 20px)
,意思是“重复 1fr 20px
模式 12 次”。IE 版本的语法是 (1fr 20px)[12]
。IE 版本具有相同的功能,只是语法不同。
/* This grid... */
.grid-one {
display: -ms-grid;
display: grid;
-ms-grid-columns: 1fr 20px 1fr 20px 1fr 20px 1fr;
grid-template-columns: 1fr 20px 1fr 20px 1fr 20px 1fr;
}
/* ...is exactly the same as this grid: */
.grid-two {
display: -ms-grid;
display: grid;
/* IE repeat syntax */
-ms-grid-columns: 1fr (20px 1fr)[3];
/* Modern repeat syntax */
grid-template-columns: 1fr repeat(3, 20px 1fr);
}
除了语法之外,现代浏览器和 IE 实现 repeat()
函数的方式之间只有一个区别。现代浏览器在该函数中添加了 auto-fit
和 auto-fill
关键字。由于 IE 不支持自动放置,因此这些关键字对 IE 来说毫无意义,所以请避免使用它们。
minmax() 在 IE 中得到本机支持
minmax()
是一个 CSS 尺寸函数,目前仅限于 CSS grid(至少目前是这样)。它的功能不言而喻。您在第一个参数中提供最小值,在第二个参数中提供最大值。应用此值的行或列将能够在这两个值之间收缩和扩展,这取决于可用的空间增加或减少。尝试调整下面的 CodePen 大小,以查看它在实际中的效果。
查看 CodePen minmax() 演示,作者是 Daniel Tonon (@daniel-tonon),发布在 CodePen 上。
人们通常认为这个很棒的小功能在 IE 中不受支持,但实际上它得到了本机支持。我猜想这至少是以下两个原因之一造成的
- 这是一个很酷的功能,他们认为 IE 无法拥有这样的酷炫功能,因为 IE 很烂。
- 每个人都看到了这个神奇的代码片段,并在意识到它在 IE 中无法运行时,他们的梦想破灭了:
grid-template-columns: repeat( auto-fit, minmax(250px, 1fr) );
。
(如果您以前从未见过这个代码片段,请观看 这段简短的视频,准备接受思维上的洗礼。)
由于神奇的代码片段在 IE 中无法运行,因此人们可能会认为代码片段中的内容都不支持 IE。实际上,代码片段无法在 IE 中复制的唯一原因是 IE 不支持 auto-fit
关键字和自动放置。
min-content 和 max-content 都 100% 支持 IE
IE 完全本机支持 min-content
和 max-content
值。
min-content
是一个关键字值,它将缩小列/行,使其达到内容可以缩小的最小可能宽度。如果应用于列,则基本上意味着该列的宽度将与最长的单词的宽度相同。
查看 CodePen min-content 演示,作者是 Daniel Tonon (@daniel-tonon),发布在 CodePen 上。
另一方面,max-content
将扩大列/行,使其达到其内容所占用的最大可能宽度,并且不会再扩大。如果您曾经在一段较长的文本上设置 white-space: nowrap
,则这看起来非常相似。
查看 CodePen max-content 演示,作者是 Daniel Tonon (@daniel-tonon),发布在 CodePen 上。
我原本并不期望 IE 支持这些值,主要是因为 minmax()
下的第一个原因。当我在研究 IE11 网格支持时,我很高兴地发现自己错了。与 minmax()
结合使用后,现代浏览器可以创建的许多网格都可以由 IE 处理(只要这些网格不涉及自动放置)。
fit-content()不支持 IE,但是…
fit-content()
在 IE 中无法正常运行。😢
幸运的是,fit-content()
是一种简写语法,当您将其写成完整形式时,IE确实支持它!🎉
完整形式是在网格模板中将 auto
(更准确地说,是 minmax(min-content, max-content)
)应用于列/行,然后在子元素上设置 max-width: [value]
。
以下是如何在现代浏览器中使用 fit-content()
函数的示例
/* This is not IE-friendly */
.grid {
display: grid;
grid-template-columns: 100px fit-content(300px) 1fr;
}
.cell {
grid-column: 2;
}
这里 fit-content()
基本上表示的是,“让中间列占用其内容的最大可能宽度(即其 max-content
值),直到它达到 300px,此时不再增长,除非被迫增长。”
查看 CodePen fit-content() 现代示例 1,作者是 Daniel Tonon (@daniel-tonon),发布在 CodePen 上。
如果您是在移动设备上阅读本文,请以横屏模式查看本节的 CodePen 演示,以便更好地理解。
为了让 IE 以相同的方式运行,您需要像这样编写代码
/* IE-friendly `fit-content()` alternative */
.grid {
display: -ms-grid;
display: grid;
-ms-grid-columns: 100px auto 1fr;
grid-template-columns: 100px auto 1fr;
}
.cell {
-ms-grid-column: 2;
grid-column: 2;
max-width: 300px;
}
查看笔 fit-content IE hack 由 Daniel Tonon (@daniel-tonon) 在 CodePen 上创建。
请注意,这不是在 IE 中复制 fit-content()
的万无一失的方法。如果另一个网格单元格具有占用宽度大于其他单元格 max-width
设置的内容,则网格列将扩展以适合较大的单元格。它不会像使用 fit-content()
那样固定在 300px。
查看笔 Broken fit-content hack 由 Daniel Tonon (@daniel-tonon) 在 CodePen 上创建。
将此与现代 fit-content()
函数进行比较,该函数会限制整个列。
查看笔 fit-content() modern example 由 Daniel Tonon (@daniel-tonon) 在 CodePen 上创建。
趁此机会,我应该澄清一下围绕 fit-content()
函数本身的一个常见误解。误解是,它所应用的列(或行)永远不能超过您提供给函数的值。事实并非如此。如果将列设置为 fit-content(300px)
的宽度,并且该列内的网格单元格设置为 400px 的宽度,则列宽度将为 400px,而不是许多人可能期望的 300px。
查看笔 Broken modern fit-content 由 Daniel Tonon (@daniel-tonon) 在 CodePen 上创建。
IE auto != 现代 auto
IE 中的 auto
值的行为与现代浏览器中的 auto
略有不同。在 IE 中,auto
严格等于 minmax(min-content, max-content)
。在 IE 中设置为 auto
的列或行永远不会收缩到小于 min-content
的大小。它也不能扩展到大于 max-content
的大小。
现代浏览器对 auto
值的处理方式略有不同。在大多数情况下,当单独使用该值时,它们仍然将 auto
视为 minmax(min-content, max-content)
。不过,有一个细微但至关重要的区别:现代浏览器中的 auto
可以通过 align-content
和 justify-content
属性进行拉伸。IE 不允许这样做。
当在现代浏览器中使用 auto
对列进行大小调整时,如果内容不足以填充列,auto
的行为更像 1fr
。IE 不会。IE 将始终将列收缩到 max-content
的大小。
因此,如果您有以下代码定义您的网格
.grid {
display: -ms-grid;
display: grid;
-ms-grid-columns: auto auto;
grid-template-columns: auto auto;
}
您将在现代浏览器中得到以下结果
…以及在 IE 中得到以下结果
好的,现代浏览器看起来很像我们使用 1fr
时得到的结果。那么,我们可以在 IE 中使用 minmax(min-content, 1fr)
吗?这样会像在现代浏览器中那样将其拉伸出来,不是吗?
是的,但我们会遇到以下问题
.grid {
display: -ms-grid;
display: grid;
-ms-grid-columns: minmax(min-content, 1fr) minmax(min-content, 1fr);
grid-template-columns: auto auto;
}
现代浏览器
IE
顺便说一下,minmax(min-content, 1fr)
本质上是 1fr
和 1fr
,并不等于 auto
。我也尝试在 IE 中使用 minmax(min-content, 100%)
,但这只是导致与使用 1fr
相同的网格外观。据我所知,不可能在 IE 中复制现代浏览器的 auto
功能。
不过,IE 和现代版本的 auto
值之间还有一个至关重要的区别。由于 IE 版本的 auto
明确等于 minmax(min-content, max-content)
,因此 auto
不能在 minmax()
表达式中使用。minmax()
不能在另一个 minmax()
函数内使用,因此 auto
被排除在外。
现代浏览器更加微妙。它们认识到 auto
在不同上下文中可能意味着不同的东西。如果单独使用,它本质上等于 minmax(min-content, max-content)
,但具有额外的拉伸能力。当用作最大值时,auto
等同于 max-content
。当用作最小值时,它本质上等于 min-content
。
如果您现在发誓永远不再在网格模板中使用 auto
,您可能需要重新考虑一下。只有三种情况下,auto
在现代浏览器和 IE 之间的行为会有所不同。这些情况是
auto
在grid-template-columns
中使用,但在同一声明中没有fr
单位。auto
在grid-template-rows
中使用,但在同一声明中没有fr
单位并且网格的高度大于其网格单元格的高度。auto
在minmax()
函数中使用。
就是这样!这些是 auto
在 IE 中的行为与在现代浏览器中行为不同的唯一时间。auto
比 minmax(min-content, max-content)
容易写得多,因此,为了几个容易避免的小浏览器不一致性而谴责它并不值得。
display: inline
元素上不起作用
(更新) IE 网格在 如果您使用 <span>
或 <a>
元素作为网格中的网格单元格,您会在 IE 中进行测试时惊讶地发现您的网格看起来不像预期。您所有的 块级元素(例如 <p>
、<div>
、<ul>
等)似乎按预期出现在网格中,但您的 内联元素(例如 <span>
、<a>
、<label>
等)将不会。
不幸的是,IE 网格无法将 display: inline
元素正确地放置到网格中。<span>
和 <a>
元素默认情况下在浏览器中设置为 display: inline
。不过,您可以在 IE 中通过将内联元素显式设置为 display: block
来轻松解决此问题。
查看笔
inline grid items don’t work in IE 由 Daniel Tonon (@daniel-tonon) 创建。
在 CodePen 上。
默认情况下,HTML 5 元素(如 <main>
、<header>
和 <footer>
)通常在浏览器中设置为 display: block
。但是,由于这些元素是在 IE11 发布之后发布的,因此 IE11 无法识别它们。无法识别的元素会还原为在不支持的浏览器中相当于 <span>
元素。这意味着,如果它们成为网格项目,它们默认情况下将不会在 IE 中工作。
您可以通过将这些现代元素显式设置为 display: block
来使它们按预期工作。或者,您可以将 normalize.css 添加到您的项目中,它会为您完成此操作。它还会执行一些其他小操作,使您的开发体验更加愉快。
我们学到了什么?
- IE 确实具有隐式网格。
- IE 支持重复功能。
minmax()
、min-content
和max-content
都得到原生支持。fit-content()
不支持,但您可以使用auto
和max-width
设置来解决这个问题。- IE
auto
不等于现代浏览器中的auto
。 - IE 网格在
display: inline
元素上不起作用。
不过,现在还不要急于使用网格。在您开始安全地将 IE 网格实现到您的网站之前,您还需要了解很多东西。请务必关注第 2 部分!我将向您展示使用仅 CSS 网格安全地为 IE 和现代浏览器构建网站所需的一切。最棒的是,您将不再需要糟糕的备用布局!
系列文章
- 打破常见的 IE Grid 误解(本篇文章)
- CSS Grid 和新的 Autoprefixer
- 使用间隙模拟自动放置网格
- 重复区域名称现在已受支持!
总之;经过这么多年和新技术的问世,我们仍然不得不为一个浏览器做出例外和更多额外的工作。
我喜欢微软在操作系统方面的进展,但那些负责浏览器的人的脑子在哪里呢?
请记住,IE 是一个遗留浏览器,自 2013 年以来就没有更新。它竟然可以与 Grid 一起使用,这真是太棒了。MS Edge 在 Grid 在 Chrome、Firefox 和 Safari 中推出时就全面支持了 Grid。
我不明白为什么要支持 IE。如果有人还在使用 IE,那么您就是在看一小部分人,而且他们可能还很尴尬。我能想到很多其他编码问题,我宁愿花时间去解决它们。
“经济上尴尬”?
哎呀。除了大多数情况下最主要的原因之外,就是在工作中使用旧的操作系统/浏览器,将那些使用旧设备的用户视为尴尬的人非常危险地精英主义。这表明我只关心像我一样的用户。
政府是我的最大原因。我在堪培拉(澳大利亚首都)工作。这里几乎所有体面的薪酬工作都来自政府客户。
政府往往拥有大量非常旧的软件,这些软件无法与现代浏览器很好地配合。由于这个原因,IE11 往往被政府设置为默认浏览器。它们也往往由很多不太懂技术的人组成。
如果你不得不使用 IE11 来完成工作,并且你不是技术精通的人,你从电子邮件中打开的每个链接都在 IE11 中打开,那么你可能将使用 IE11 来完成所有事情。如果你是一个为政府客户构建内网的开发人员,那么你可能面临着 90% 到 99% 的 IE11 用户群!你认为你不能支持 IE11 吗?
如果你正在构建一个公共政府网站,客户可能会在 IE11 中经常查看它。你可以告诉他们用 Chrome 查看,但链条中的某个人会在 IE11 中查看网站,看到布局很糟糕,然后要求你修复它。打破客户头脑中“所有浏览器都需要看起来一样”的想法可能很困难。不是每个人都能做到。
另一个主要原因是电子商务网站。IE11 浏览器使用率仍然在 2%-3% 之间。如果你给 2%-3% 的用户提供糟糕的体验,那就意味着成千上万美元的收入损失。
我可能应该在文章开头就提到这些内容 :/
我在一家为电影和电视公司制作 B2B 产品的公司工作。我们的一位主要客户将 IE 作为公司电脑的唯一浏览器。他们一点也不“经济拮据”,我怀疑当公司 IT 部门介入时,这个“非常小的”群体并不那么小;升级这些系统需要比我们希望的长得多的时间。(当我回想起我们必须支持 IE8 多久,因为公司仍然使用 Windows XP,并且实际上无法再升级 IE 时,我感到不寒而栗。)
公共网站可能不再需要支持 IE11 了。但是,如果你正在为内网编写内容,那么 IE11 将一直存在,直到它获得安全补丁,这可能是直到 2022 年(Windows 8 和 Server 2012 R2 停产)。
我们编写医疗记录软件,尽管我很想放弃 IE 支持,但这在现实中不可行。我一直想利用网格,因为它可以真正简化我们的大部分布局,所以这篇文章给了我很多思考的空间。
我正在开发的产品被英国和北美的顶级金融投资者和银行机构使用。
这些人与你定义的“经济拮据”完全相反,并且可能是那些在你的日常交易中处理你资金的人。
IE 是我们平台上使用率第二高的浏览器。
我对这件事感到高兴吗?当然不。我还有更好的问题要解决吗?当然!
像上面那样的详细文章对于这个原因非常宝贵。
我想使用网格等闪亮的新功能来解决编码问题,我感谢那些分享他们如何做到这一点而不会影响我们平台上用户活动的人。
我对 IE11 的这种重复语法有点困惑。
编写
-ms-grid-columns: 1fr (1rem 1fr)[4];
被 scss-lint 视为语法错误。[4]
部分是意外的……我找不到任何关于如何禁用“语法”代码检查的线索。很多关于如何禁用特定规则,但对于语法,则什么都没有。
有人有想法吗?
答案:不要在源代码中放 IE 语法。让 Autoprefixer 为你执行 IE 转换。我在第 2 部分中介绍了如何做到这一点。
感谢你花时间写这篇文章,知道可以在 IE 中提供支持真是太好了。
目前很难扫描文章并了解哪些是支持的,哪些是不支持的,以及是否存在任何变通方法——你认为你可以提供一个支持内容、不支持内容以及是否存在任何变通方法的摘要表吗?
例如
把这篇文章看作是第 2 部分主菜之前的开胃菜。然后第 3 部分是一点甜点。
我在第 2 部分中做了你要求的事情。我制作了 Rachel Andrews IE CSS 网格文章 中的兼容性表的更新版本。
我可能会在后续文章中做一个更全面的表格。
我测试了一些这些东西,但不幸的是,所谓的“重复”功能在 Windows 7 上的 IE 11 中不起作用(我在 Virtual Box 中运行它)。所有东西都只是崩溃了。
无法使用它,加上你无法添加间隙,使得它对我的项目来说实际上不可用。我们不断有新的开发人员和实习生加入,他们中的大多数人知识很少,需要学习我们内部使用的入门主题,才能快速制作网站。
因此,我们使用的任何系统都必须健壮,至少有一点直观,易于阅读且易于跨浏览器修复。当我开始阅读这篇文章时,我感到很欣慰,但对我来说仍然很清楚的是,CSS 网格的状态离这种工作方式还有很长的路要走。它对经验丰富的开发人员来说是开放的,他们足够快地完成工作,可以花更多时间制作自己的自定义网格内容,但仅此而已。
在我看来,你试图在 IE 中使用自动放置。IE 不支持自动放置。但这并不意味着 IE 中的 CSS 网格实现毫无用处。如果你在已知的行数和列数中拥有已知的单元格数,那么 IE 中的实现非常有用。
不要放弃希望!这只是 3 部分中的第一部分。在第 2 部分结束时,你(以及你的所有初级开发人员)将能够非常轻松地在 IE 中使用 CSS 网格。
感谢关于 IE 和现代浏览器中 auto 的解释,我解决了我在 IE11 中响应式的问题。我只是将 auto 更改为 1fr(在我的情况下完美地工作),现在当我缩小浏览器窗口时,我的布局会很好地缩小。之前我认为这是 min-content 问题。现在我将尝试使用 repeat。
感谢这篇文章,我期待着第 2 部分和第 3 部分。我一定能学到新东西。
在我们称这种立场为精英主义之前,请考虑一下,世界上视觉障碍的人比使用 IE 11 的人更多。
WCAG AA/AAA 合规性应优先于 IE 11 兼容性。
这个系列来得太及时了。我昨天花了大约一个小时搜索关于如何使自定义 CSS 网格网格系统与 IE 兼容的最佳实践。说实话,我仍然不确定如何用这篇文章中提供的信息来做到这一点,但我希望这个系列中的第 2 部分和第 3 部分能解答这个问题。
Internet Explorer 真是太痛苦了,不得不做这些事情,但对于很多,甚至大多数工作来说,支持 IE 是必要的。感谢这篇文章。
非常感谢你写这篇文章!这些信息让我在工作和个人项目中更多地尝试使用 CSS 网格,并且意识到这个功能强大的力量。我迫不及待地等待着第 2 部分!你预计什么时候完成它并发布它?
我有一个快速的问题,我遇到了一些问题。我有一个使用
-ms-grid-rows: 75px 1fr 85px
的简单布局,但 IE 11 并不尊重这些行,它们最终在页面顶部重叠。你对此有任何想法吗?我确实使用了 Autoprefixer 来获取 CSS 语法。