3 种在任何浏览器中使用 CSS 网格的后备方案

发表于 3年以前  | 总阅读数:300 次

如今,CSS Grid 在浏览器中已经广受支持 —— 支持 Grid 基本功能的浏览器占比约为 95%。不过有时我们无法忽略剩下的 5%,因为我们可能希望自己的 Web 应用的布局在所有浏览器中看起来都一样的棒,而且我们甚至还可能希望去使用一些支持度较低的 Grid 的新功能。

那我们应该做什么?我们应该避免在生产中使用 Grid 布局吗?我们应该抛弃使用旧版浏览器的用户吗?我们应该等待功能得到更好的覆盖吗?当然不,有很多后备方案可以帮助我们克服这些问题。

在本文中,我们将探讨最重要的三种技术。它们将帮助我们在 Grid 布局上轻松兼容旧版浏览器,这样我们就可以根据可用的浏览器功能,调整我们的网页设计。这一切都将是渐进式适应的。

在深入探讨技术方面的内容之前,我们需要制定一个策略。制定适当的策略是成功的关键,因为这将使我们有方向感和一致性。

制定策略

Grid 中最常见的用处是构建适合用户屏幕分辨率的多维栅格布局。但当栅格不可用时该怎么办?除了 Grid 之外,还有什么东西可以帮助我们制作灵活且迅速响应的布局?

我们可以尝试使用 Flexbox 重现相同的布局,不过这样做会增加过多的代码。此外,Flexbox 也不是为了栅格布局而开发的功能,如果使用它,我们可能会遇到一些困难。

现在我们该怎么办?解决方案非常简单:作为后备方案,只需向用户展示移动端的布局即可,而只有使用过时浏览器的桌面端用户才会注意到这些改变。他们在我们的总用户数量中占比非常低。你的站点对于所有人来说应该都是可以使用且一致的,而这就是一个公平的权衡。

那么如何使用最新的 Grid 功能?直接采取相同的策略:尝试回退到一个相似的布局。

总结:我们的布局应该逐步增强。使用较旧浏览器的用户可能只能看到一个更简单但可用的版式,而那些使用最新浏览器的用户将获得完整的用户体验。

让我们来看一下可以使用的前 3 种后备工具。

  1. 使用 CSS 特性查询

让我们从下面的这段描述开始了解:

特性查询 是使用 CSS 的 at 规则 @supports 创建的。它给予 Web 开发者一种有效的方法去测试浏览器是否支持某个确定特性,而后提供基于测试结果生效的 CSS 。在此指南中你将学习如何使用特性查询实现渐进式增强。” — [MDN Web文档](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Conditional_Rules/Using_Feature_Queries)

如果你曾经使用过媒体查询,那么我想,你也会非常熟悉 @supports 的语法,毕竟两者是很相似的。不过在这里我们使用 @supports 不是希望基于浏览器的视口大小来调整布局,而是希望基于 CSS 属性的支持与否来定义指定的样式。

根据我们的策略:

1.我们将使用 Flexbox 构建移动布局版本,并将其用作默认版本。2.通过使用 @supports,我们将检查浏览器是否支持 Grid。如果支持,我们就会使用 Grid 来增强布局。

在此示例中,由于我们仅需关注标准的 Grid 行为。在这里我们可以向 @supports 查询基本的 display:grid 功能:

@supports (display: grid) {
    /* ... code here */
}

完整的例子如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>生产中的 Grid</title>
    <meta charset="UTF-8"/>
</head>

<body>
<style>
    #container {
        display: flex;
        flex-direction: column;
        gap: 10px;
        border: 1px solid #000;
        padding: 10px;
    }

    @supports (display: grid) {
        #container {
            display: grid;
        }

        @media (min-width: 768px) {
            #container {
                grid-template-columns: 100px 1fr 100px;
            }
        }
    }

    .side1 {
        padding: 10px;
        background-color: #CEB992;
    }

    .side2 {
        padding: 10px;
        background-color: #CEB992;
    }

    .content {
        padding: 10px;
        min-height: 400px;
        background-color: #5B2E48;
    }

    body {
        color: #FFF;
        font-weight: 500;
    }
</style>
<div id="container">
    <div class="side1">
        侧边栏
    </div>
    <div class="content">
        主要内容
    </div>
    <div class="side2">
        侧边栏
    </div>
</div>
</body>
</html>

注意,我们并没有断言 Grid 特性 grid-template-columns。如果浏览器不支持该怎么办?在这种情况下,Grid 将退回到默认的定位算法 —— 它将堆叠 div。在我们的示例中,该方法可以正常运行,因此我们不需要再去进行额外的工作。

让我们看看结果,这是支持 Grid 的浏览器的桌面端视图结果:

支持 Grid 时的布局

这是支持 Grid 的浏览器的移动端视图的结果:

支持 Grid 时的布局

这是不支持 Grid 的浏览器的任何视图下的结果:

Fallback 布局

布局没有被破坏,仍然可用于所有浏览器引擎。只有从桌面端访问它的用户才能看到区别。

  1. 以编程方式使用 CSS 功能查询

有时,仅通过样式表中的 CSS 特性查询无法实现我们想要的功能。尽管它的功能强大,但也有局限性。因此我们可能需要基于浏览器功能,以编程的方式添加或删除元素。那应该如何实现呢?

幸运的是,可以在 JavaScript 以编程方式调用 CSS 功能。我们可以通过 CSS 对象模型接口 CSSSupportsRule 来访问 @supports

CSSSupportsRule 接口代表一个 CSS @supportsat-rule — [MDN Web文档](https://developer.mozilla.org/en-US/docs/Web/API/CSSSupportsRule)

让我们看一下它的定义:

function supports(property: string, value: string): boolean;

我们在一个假设的案例中使用看看。如果用户使用的浏览器不支持 Grid 布局功能,它就会给用户发出警告。不过我们可不能在生产环境中这样做,这只是一个有趣的例子。

这是我们有条件地检查是否不支持 Grid 的方式:

if (!CSS || !CSS.supports('display', 'grid')) {
    // ...
}

请注意,某些浏览器可能不支持 CSS.supports,因此我们还添加了空检查。

让我们来看一个有效的代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>生产中的 Grid</title>
    <meta charset="UTF-8"/>
</head>
<body>
<style>
    #container {
        display: flex;
        flex-direction: column;
        gap: 10px;
        border: 1px solid #000;
        padding: 10px;
    }

    @supports (display: grid) {
        #container {
            display: grid;
        }

        @media (min-width: 768px) {
            #container {
                grid-template-columns: 100px 1fr 100px;
            }
        }
    }

    .side1 {
        padding: 10px;
        background-color: #CEB992;
    }

    .side2 {
        padding: 10px;
        background-color: #CEB992;
    }

    .content {
        padding: 10px;
        min-height: 400px;
        background-color: #5B2E48;
    }

    body {
        color: #FFF;
        font-weight: 500;
    }
</style>
<script>
    (function warnSupport() {
        if (!CSS || !CSS.supports('display', 'grid')) {
            alert('Warning your Browser does not support the latests features. Consider switching to a newer one')
        }
    })();
</script>
<div id="container">
    <div class="side1">
        侧边栏
    </div>
    <div class="content">
        主要内容
    </div>
    <div class="side2">
        侧边栏
    </div>
</div>
</body>
</html>

CSS.supports 是用于以编程方式创建后备布局的优秀工具。如果我们必须处理非常复杂的布局,那么我们可能需要选用此方法而不是 CSS 特性查询。有了这种程序化的后备方案,我们可以使用它来创建 Web 组件。

  1. 属性覆盖

有时候,我们不需要 CSS 特性查询之类的奇特功能。这时,我们就可以利用 CSS 属性的工作原理:在 CSS 类中重新定义属性时,最后一个有效的属性会被视作要使用的属性。

这是什么意思?为什么说它好用呢?我们可以通过覆盖 CSS 属性来定义后备样式:

#container {
    display: flex;
    display: grid;

    /* 如果 Grid 不可用,则第二个属性声明将失效,且浏览器会应用第一个属性声明的值 `flex` */
}

我们可以以更简单的方式重写先前的 CSS 特性查询示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>生产中的 Grid</title>
    <meta charset="UTF-8"/>
</head>
<body>
<style>
    #container {
        display: flex;
        display: grid;
        flex-direction: column;
        gap: 10px;
        border: 1px solid #000;
        padding: 10px;
    }

    @media (min-width: 768px) {
        #container {
            grid-template-columns: 100px 1fr 100px;
        }
    }

    .side1 {
        padding: 10px;
        background-color: #CEB992;
    }

    .side2 {
        padding: 10px;
        background-color: #CEB992;
    }

    .content {
        padding: 10px;
        min-height: 400px;
        background-color: #5B2E48;
    }

    body {
        color: #FFF;
        font-weight: 500;
    }
</style>
<script>
    (function warnSupport() {
        if (!CSS || !CSS.supports('display', 'grid')) {
            alert('Warning your Browser does not support the latests features. Consider switching to a newer one')
        }
    })();
</script>
<div id="container">
    <div class="side1">
        侧边栏
    </div>
    <div class="content">
        主要内容
    </div>
    <div class="side2">
        侧边栏
    </div>
</div>
</body>
</html>

这种后备方案虽然简单但是功能强大。在许多情况下它很有用 —— 毕竟我们可能无法对所有要使用的 Grid 功能都进行查询。

让我们用它从最新的 Grid 功能之一:subgrid 进行回退吧。我们应该如何使用呢?

让我们想象一下需要对嵌套的 Grid 模板列使用 subgrid 的场景,划重点:

#content {
    grid-template-columns: inherit;
    grid-template-columns: subgrid;
}

在此示例中,当不支持 subgrid 时候,它将仅继承父级的 Grid 定义。这将创建一个大致相似的布局。

这只是一个简单的例子。我们可以将 grid-template-columns 微调到某些固定大小,或者在我们的特定情况下最适合的大小。

这是完整的示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Grid 案例</title>
    <meta charset="UTF-8"/>
</head>
<body>
<style>
    body {
        color: white;
        text-align: center;
        box-sizing: content-box;
        margin: 20px;
    }

    .palette-1 {
        background-color: #CEB992;
    }

    .palette-2 {
        background-color: #471323;
    }

    .palette-3 {
        background-color: #73937E;
    }

    .palette-4 {
        background-color: #5B2E48;
    }

    .palette-5 {
        background-color: #585563;
    }

    #container {
        padding: 10px;
        background-color: #73937E;
        height: 500px;
        width: calc(100vw - 60px);
        display: grid;
        grid-template-rows: repeat(8, 1fr);
        grid-template-columns: max-content 1fr 1fr 1fr;
        row-gap: 1rem;

    }

    .item {
        padding: 20px;
    }

    .content-main {
        grid-column: span 3;
    }

    #content {
        background-color: #73937E;
        grid-column: 1 / -1;
        display: grid;
        grid-template-columns: inherit;
        grid-template-columns: subgrid;
        column-gap: 1rem;
    }


</style>
<div id="container">
    <div id="content">
        <div class="content-left item palette-5">
            标题
        </div>
        <div class="content-main item palette-4">
        </div>
    </div>
    <div id="content">
        <div class="content-left item palette-5">
            另一个标题
        </div>
        <div class="content-main item palette-4">
        </div>
    </div>
</div>
</script>
</body>
</html>

至于结果:

如你所见,结果看起来是完全一致的,但其实只是非常相似而已,这就是我们的目标。随着越来越多的浏览器采用 subgrid,更多的用户都可以看到布局的像素级完美版本!

结论

Grid 和 Flexbox 旨在解决不同的情况。我们无法一直使用 Flexbox 构建所有布局,因为仍然有少数浏览器不支持它。

从 Flexbox 升级到 Grid 并不意味着布局在旧设备上突然失效。在本文中,我们探讨了构建渐进式布局有多么容易和有趣。正如我们在一开始所看到的那样,制定一项如何进行的策略非常重要。

这些策略不仅仅是为了添加基本的 Grid 功能。只要我们提供合理的后备方案,我们就可以利用诸如 subgrid 之类的最新功能。

我希望这能鼓励你在需要时去生产环境中逐渐应用 Grid。现在,我们不必再躲在 Flexbox 后面了!

本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/QYP1vebmd3NJhKMRRj2Irw

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:6月以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:6月以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:6月以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:6月以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:6月以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:6月以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:7月以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:6月以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:6月以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:6月以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:6月以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:6月以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:6月以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:6月以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:6月以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:7月以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:7月以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:7月以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:6月以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:6月以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  236812次阅读
vscode超好用的代码书签插件Bookmarks 1年以前  |  6665次阅读
 目录