为什么QQ浏览器在 flex 排版上和别的浏览器不一样呢?

小明
  • 22

大家好,我在用 flex 排版一个网页时发现了一个问题:同样的代码在 QQ 浏览器的显示效果和别的浏览器不一样。我写了一个示例页面来简化并演示我遇到的问题。下面分别是 fiefox 浏览器显示效果(正常)、edge 浏览器显示效果(正常)和 QQ 浏览器显示效果(不正常)。代码我放到最后。

firefox.png
上面这张图是 firefox 的正常显示效果。

edge.png
上面这张图是 edge 的正常显示效果。

qq_o.png
上面这张图是 QQ 浏览器的不正常展示。

这是我的 html 代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=divice-width, initial-scale=1.0">
    <title>
    测试 flex
    </title>
    <link rel="stylesheet" type="text/css" href="test.css" />
</head>
<body>
<div class="left">左边不重要</div>
<div class="right">
    <div class="right_head">
        <div class="right_head_title">
            这里是文章标题
        </div>
        <div class="right_head_des">
            这里是文章描述,这篇文章有一百万亿个字,需要阅读一万年。
        </div>
    </div>
    <div class="right_main">
        <div class="right_main_article">
            <h1>1.这里是第一个标题</h1>
            <p>
            旧历的年底毕竟最像年底,村镇上不必说,就在天空中也显出将到新年的气象来。灰白色的沉重的晚云中间时时发出闪光,接着一声钝响,是送灶的爆竹;近处燃放的可就更强烈了,震耳的大音还没有息,空气里已经散满了幽微的火药香。我是正在这一夜回到我的故乡鲁镇的。虽说故乡,然而已没有家,所以只得暂寓在鲁四老爷的宅子里。他是我的本家,比我长一辈,应该称之曰“四叔”,是一个讲理学的老监生。他比先前并没有什么大改变,单是老了些,但也还末留胡子,一见面是寒暄,寒暄之后说我“胖了”,说我“胖了”之后即大骂其新党。但我知道,这并非借题在骂我:因为他所骂的还是康有为。但是,谈话是总不投机的了,于是不多久,我便一个人剩在书房里。
            </p>
            <figure>
                <img src="image.jpg" alt="测试图片">
            </figure>
            <h1>2.这里是第二个标题</h1>
            <p>
            第二天我起得很迟,午饭之后,出去看了几个本家和朋友;第三天也照样。他们也都没有什么大改变,单是老了些;家中却一律忙,都在准备着“祝福”。这是鲁镇年终的大典,致敬尽礼,迎接福神,拜求来年一年中的好运气的。杀鸡,宰鹅,买猪肉,用心细细的洗,女人的臂膊都在水里浸得通红,有的还带着绞丝银镯子。煮熟之后,横七竖八的插些筷子在这类东西上,可就称为“福礼”了,五更天陈列起来,并且点上香烛,恭请福神们来享用,拜的却只限于男人,拜完自然仍然是放爆竹。年年如此,家家如此,——只要买得起福礼和爆竹之类的——今年自然也如此。天色愈阴暗了,下午竟下起雪来,雪花大的有梅花那么大,满天飞舞,夹着烟霭和忙碌的气色,将鲁镇乱成一团糟。我回到四叔的书房里时,瓦楞上已经雪白,房里也映得较光明,极分明的显出壁上挂着的朱拓的大“寿”字,陈抟老祖写的,一边的对联已经脱落,松松的卷了放在长桌上,一边的还在,道是“事理通达心气和平”。我又无聊赖的到窗下的案头去一翻,只见一堆似乎未必完全的《康熙字典》,一部《近思录集注》和一部《四书衬》。无论如何、我明天决计要走了。
            </p>
            <h1>3.这里是第三个标题</h1>
            <p>
            况且,一直到昨天遇见祥林嫂的事,也就使我不能安住。那是下午,我到镇的东头访过一个朋友,走出来,就在河边遇见她;而且见她瞪着的眼睛的视线,就知道明明是向我走来的。我这回在鲁镇所见的人们中,改变之大,可以说无过于她的了:五年前的花白的头发,即今已经全白,全不像四十上下的人;脸上瘦削不堪,黄中带黑,而且消尽了先前悲哀的神色,仿佛是木刻似的;只有那眼珠间或一轮,还可以表示她是一个活物。她一手提着竹篮。内中一个破碗,空的;一手拄着一支比她更长的竹竿,下端开了裂:她分明已经纯乎是一个乞丐了。
            </p>
        </div>
        <div class="right_main_footnote">
        这里是脚注。
        </div>
    </div>
    <div class="right_comments">
        <p>写得真好!</p>
        <p>写得真好!</p>
        <p>写得真好!</p>
        <p>写得真好!</p>
        <p>写得真好!</p>
        <p>写得真好!</p>
        <p>写得真好!</p>
        <p>写得真好!</p>
        <p>写得真好!</p>
        <p>写得真好!</p>
        <p>写得真好!</p>
        <p>写得真好!</p>
    </div>
</div>
</body>
</html>

这是我的 CSS 代码:

@charset"utf-8";
*{
    border-width: 0;
    margin: 0;
    padding:0;
}
body {
    display: flex;
    overflow: hidden;
    height: 100vh;
}
.left{
    display: flex;
    order: 1;
    width: 25vw;
    height: 100vh;
    background-color: red;
}
.right{
    display: flex;
    flex-direction: column;
    order: 2;
    padding-left: 2rem;
    padding-right: 2rem;
    overflow-y: auto;
    height: 100vh;
    background-color: yellow;
}
.right_head{
    display: flex;
    flex-direction: column;
    order: 1;
    padding-top: 5rem;
    padding-left: 5rem;
    padding-right: 5rem;
    background-color: lightblue;
}
.right_head_title{
    display: flex;
    order: 1;
    font-size: 2.3rem;
    font-weight: 600;
    background-color: orange;
}
.right_head_des{
    display: flex;
    order: 2;
    font-size: 1.25rem;
    background-color: lightgrey;
}
.right_main{
    display: flex;
    flex-direction: column;
    order: 2;
    padding-top: 5rem;
    margin-left: 6%;
    margin-right: 6%;
    margin-bottom: 3rem;
    background-color: lightgreen;
}
.right_main_article{
    display: flex;
    flex-direction: column;
    order: 1;
    font-size: 1.2rem;
    margin-left: 3rem;
    margin-right: 3rem;
    margin-bottom: 3rem;
/*我自己试来试去找到了一个问题*/
    overflow-x: auto;
    overflow-y: hidden;
/*把这两行删掉可以让段落都显示出来*/
    background-color: ivory;
}
.right_main_article h1{
    margin-bottom: 0.6rem;
    margin-left: 2rem;
    margin-right: 2rem;
    font-size: 1.8rem;
    font-weight: 800;
    background-color: cyan;
}
.right_main_article p{
    margin-bottom: 0.6rem;
    margin-left: 1.5rem;
    margin-right: 1.5rem;
    text-indent: 2.4rem; /* article font-size 的二倍,确保是空了两个格.*/
    line-height: 160%;
    background-color: darkorange;
}
.right_main_footnote{
    display: flex;
    order: 2;
    margin-left: 2rem;
    margin-right: 2rem;
    background-color: pink;
}
.right_comments{
    display: flex;
    flex-direction: column;
    margin-left: 8rem;
    margin-right: 8rem;
    background-color: grey;
    color: white;
    order: 3;
}

我自己发现了一个问题,即,把 CSS 代码中的第 69-72 行注释掉能让 QQ 浏览器把第二个段落显示出来,但问题依旧没有解决,请看:
qq.png
上面这张是把那几行注释掉以后的 QQ 浏览器的显示效果。

首先能排除是 flex 兼容问题引起的。这是因为我在网上搜索了一下,发现了这个神奇的网站: https://autoprefixer.github.io/ 我选它默认的 last 4 version 帮我把 CSS 都纠正了一遍以便兼容大多数浏览器,但问题依旧,所以我觉得不是这个问题。CSS 代码为了更简单,上面只是贴了原始代码。

我的问题就是:为什么 QQ 浏览器的显示效果是这样的呢?这是 QQ 浏览器的 bug 么?我觉得我 flex 的用法应该没问题吧?(都是照着阮一峰老师的博客学习的,而且别的浏览器也都挺正常的。)还是说,我的 flex 用法其实并不标准,是 forefox edge 等浏览器自动帮我搞好了?

我并不是一个专业的前端,甚至都不是程序员,我只是在自己试着写一个博客的时候边学边搞,最后遇到了这个问题。我有点不太清楚这个问题该怎么描述,所以也没查到什么对我有用的信息,所以就来这里请教一下大家。我的代码写得很啰嗦,请大家不要嘲笑我。

回复
阅读 1.5k
2 个回答
✓ 已被采纳

大家好!在评论区一位大佬的启发下我发现了问题的关键。

本质上,是在 flex container 上如果设置了 overflow-y: autoheight: 100vh ,QQ 浏览器就会试图把这个 container 中的所有东西都在一个屏幕高度内塞下,塞不下它就会覆盖,导致显示异常。而其他浏览器(firefox, chrome, edge)就不会这么愚蠢。如果这两句确实不能删掉(比如我希望固定左边栏,右边进行滚动),知道了问题的关键也就容易解决了。

解决的方法是在每个 flex-item 中加上 flex-shrink: 0 。这是因为默认情况下 flex-shrink 的值是 1,表示空间不够的时候等比例压缩,改成 0 就可以让愚蠢的 QQ 浏览器不做蠢事了,而其他浏览器也都没问题。

示例代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=divice-width, initial-scale=1.0">
    <title>flex 纵向排列问题展示</title>
    <style>
    .flex-container{
        overflow-y: auto; /*这两行非常关键,没有这两行不会产生问题*/
        height: 100vh; /*这两行非常关键,没有这两行不会产生问题*/
        display: flex;
        flex-direction: column;
        background-color: lightyellow;
    }
    .flex-item-up{
        display: flex;
        order: 1;
        /* 只要加上这一行,问题就能迎刃而解了:
        flex-shrink: 0;
        */
        background-color: lightgrey;
    }
    .flex-item-middle{
        display: flex;
        order: 2;
        /* 只要加上这一行,问题就能迎刃而解了:
        flex-shrink: 0;
        */
        background-color: lightgreen;
    }
    .flex-item-bottom{
        display: flex;
        order: 3;
        /* 只要加上这一行,问题就能迎刃而解了:
        flex-shrink: 0;
        */
        background-color: lightblue;
    }
    .object{
        border:5px solid black;
        margin:30px;
        width: 600px;
        height: 400px;
        background-color: pink;
    }
    </style>
</head>
<body>
<div class="flex-container">
    <div class="flex-item-up">
        <div class="object"></div>
    </div>
    <div class="flex-item-middle">
        <div class="object"></div>
    </div>
    <div class="flex-item-bottom">
        <div class="object"></div>
    </div>
</div>
</body>
</html>

这个问题比较简单,我就不截效果图了。真是没想到这么简单的问题竟然折磨了我这么久。。。。。。。。请大佬们不要嘲笑我。。。。。。

你知道吗?

宣传栏