ホームページ  >  記事  >  ウェブフロントエンド  >  タオバオの柔軟なレイアウト ソリューション lib-flexible_html/css_WEB-ITnose に基づく課題の調査

タオバオの柔軟なレイアウト ソリューション lib-flexible_html/css_WEB-ITnose に基づく課題の調査

WBOY
WBOYオリジナル
2016-06-21 09:00:191148ブラウズ

前回の記事「淘宝網フレキシブル レイアウト ソリューション lib-flexible の実践」では、lib-flexible の基本的な使用法を説明するために簡単な例を組み合わせましたが、lib-flexible のこの適応方法は適応に含まれています。ビューポートの初期スケールが変更されると、ビューポートの幅はデバイスの幅と等しくないため、幅に基づいて作成されたメディア クエリは必ずしも期待と一致しません。また、古典的な Retina スクリーン画像の問題もあります。 lib でのモバイル Web の 1px 境界の問題 - Flexible も通常とは異なります。この記事の内容は、これらのことを研究し、独自の考えと解決策を提案することです。 1. lib-flexible はレスポンシブ レイアウトと互換性がありません まずレスポンシブ レイアウトの基本的な理解について説明します。 レスポンシブ レイアウトのパフォーマンスは次のとおりです。 pass css メディア クエリは、表示領域の幅を決定し、さまざまな範囲にさまざまなスタイルを適用して、さまざまなサイズのデバイスに最適なインターフェイス効果を提供します。典型的な例としては、レスポンシブ レイアウトを適用すると、PC では 4 列、タブレットでは 3 列、携帯電話では 1 列のみ表示される商品一覧ページがあります。このレイアウトの最大の利点は、人的資源、リソース、時間を節約できるため、多くの企業がこのレイアウトを使用することを好みます。レスポンシブ レイアウトには 2 つの必要な要件があります: 1) ビューポートの幅と初期スケールは、ビューポートの幅がデバイスの幅と同じになるように次の構成を採用する必要があります。 : 2) は、メディア クエリを使用して、ブートストラップなどのさまざまな幅の範囲に対して異なる CSS を記述することです: 注意すべき点: で言及されているデバイス幅(1) 要件は、メディア クエリの device-width 属性と同じです。意味は多少異なります。最初の要件 (1) で言及されているデバイス幅は、モバイル デバイス上のデバイスの幅を指しますが、PC ではそれを指します。たとえば、次の Web ページでは、ブラウザ ウィンドウを縮小しました。ビューポートでは幅が device-width に設定されていますが、Web ページのサイズは変更されていないことがわかります。デスクトップの解像度の幅 (デバイスの幅): メディア クエリの device-width 属性は、常にデバイスの幅を指します。したがって、レスポンシブ レイアウトのメディア クエリでは、device-width 属性ではなく width 属性を使用する必要があります。これは、デスクトップ デバイスでは、ブラウザ ウィンドウが縮小されてもデバイス幅は変化せず、デバイス幅が表示されなくなるためです。ブラウザウィンドウのサイズがレスポンシブ効果に変更されます。 lib-flexible の特性を見てみましょう: lib-flexible は適応中にビューポートの初期スケールを変更し、ビューポートの幅がデバイスと等しくなりません。幅。これは、lib-flexible を使用して iPhone6 Plus に適応した後に自動的に追加されるビューポート設定コードです: このビューポートのアクションでは、Web ページの倍率は 0.3333333333333333、デバイス幅は 0.3333333333333333 です。 iphone6 plus スケーリング後のビューポートの幅は、スケーリングされていない CSS ピクセル 414 で、デバイスの幅 / 0.333333333333333 に等しくなります。これは、スケーリングされた CSS ピクセル 1242 であり、デバイスの幅よりもはるかに大きくなります。 🎜> Web ページでレスポンシブ レイアウトと lib-flexible の両方を使用する必要があり、1024 ピクセルを超える解像度 (デスクトップ デバイス) で特定のスタイルをレンダリングする必要があるメディア クエリを作成した場合 (コードは単なる例です) ): このページは iPhone6 plus のメディア クエリ スタイルにも適用されることがわかります: 理由は: Web iPhone6 Plus のページは lib-flexible によるものです。その結果、ページの幅は実際の物理解像度の幅、つまり 1242 ピクセルと等しく、メディア クエリの範囲に完全に達します。 したがって、lib-flexible を使用するプロジェクトでレスポンシブ レイアウトを実装することは困難です。この 2 つを組み合わせて使用​​することを考えている人は注意してください。実際、2 つのソリューションは本質的に異なり、適用可能なシナリオも異なります。レスポンシブ レイアウトの目的は、携帯電話、タブレット、PC で適切に表示できるコードのセットであり、Web サイトのプロジェクトに適しています。一方、lib-flexible は、タブレットと PC の違いに関係なく、モバイル Web ページの適応問題を解決します。 PC の場合、Web アプリのプロジェクトに適しています。 2. lib-flexible で 1px の境界線を処理する方法 Web アプリでは、CSS を使用して境界線を直接 1px に設定する場合があります。 > その結果、携帯電話ではこの種の境界線が特に太く見えることがわかります。この効果の理由は非常に単純で、現在のほとんどの携帯電話の解像度が非常に高いためです。上記のコードの 1px は、2 または 3 物理解像度ピクセルに相当する場合があります。PC とは異なり、CSS ピクセルは常に 1 物理解像度ピクセルに等しいため、携帯電話で表示される 1px は実際の厚さよりも大きくなります。 この問題を解決するには、1px の代わりに 0.5px を使用することを考えるかもしれませんが、これでは問題は解決できません。また、小数点以下のピクセルはブラウザによって間違いなく落とし穴となるため、最善を尽くして回避する必要があります。 。 それでは、Web アプリで 1px を表示する通常の方法は何でしょうか? 少し前に weui のソース コードで優れた方法を見つけました。これは共有する価値があります。

//这是一个mixin,用来设置顶部的边框,其它方向的代码没有贴出.setTopLine(@c: #C7C7C7) {    content: " ";    position: absolute;    left: 0;    top: 0;    width: 100%;    height: 1px;    border-top: 1px solid @c;    transform-origin: 0 0;    transform: scaleY(0.5);}//应用举例.weui_cell {    // onepx    position: relative;    &:before {        .setTopLine(@weuiCellBorderColor);    }}

这个办法并不是利用border属性来显示边框,而是利用了伪类和transform,最妙的是这个transform,0.5px办不到的事情,它却办得到。

由于lib-flexible在适配的时候,会缩放网页,导致css代码中的1px等于物理分辨率的1px,这样子这个1px边框的问题在经过lib-flexible适配的设备下就很好解决了,直接应用border: 1px solid;即可。但是 lib-flexible现在只适配了iphone设备,安卓设备压根没适配 :

导致在安卓设备下,1px的边框问题依然存在。所以为了在lib-flexible的项目里解决1px的问题,就得综合两种做法了:

.setTopLine(@c: #C7C7C7) {  & {    position: relative;  }  &:before {    content: " ";    position: absolute;    left: 0;    top: 0;    width: 100%;    height: 1px;    border-top: 1px solid @c;  }  [data-dpr="1"] &:before {    transform-origin: 0 0;    transform: scaleY(0.5);  }}/*照着这个可以再写setBottomLine等相关mixin*/

这个做法,我做过测试,在我devicePixelRatio为3的meilan note上,显示出的线条非常细腻,看起来很舒服,iphone的效果也不错,借别人的机子测试过,所以有兴趣的人可以借鉴使用,有问题尽管提出,看看能不能有更好的办法解决。这是我用魅蓝note做测试的截图:

第1根线是上面的mixin效果;第二根线是直接使用border: 1px solid的效果。

注:以上提到的这个1px边框的做法有三个缺点,在使用的时候需要注意:

1)它会占用掉before伪类

2)没法做圆角

3)很难实现多条边框,除非嵌套,或者再利用上after伪类。

尽管如此,以上这个做法还是非常有用的做法,因为这种细线边框属于比较特殊的设计要求,并不是每处边框都得做成这样,在开发webapp的时候用这个方法保证特殊线条的设计要求,其它的边线,我觉得直接用border并没有关系,你可以直接用你的手机打开bootstrap的官方页面,看它里面的按钮边框,效果都还不错。

3. lib-flexible如何处理retina屏下的background-image

几年之前,retina屏,也就是所谓的高清屏,还不像现在这么普遍,12年我买的第一个安卓机是华为u8825d,分辨率只有480*800,而且当时市面上大部分安卓机基本上都是这个分辨率,像iphone4 那种640*960级别的机子很少,为了解决普通背景图片在iphone4下显示模糊的问题,基本都是采用这种做法:

.css{/* 普通显示屏(设备像素比例小于等于1.3)使用1倍的图 */     background-image: url(img_1x.png);}@media only screen and (-webkit-min-device-pixel-ratio:1.5){.css{/* 高清显示屏(设备像素比例大于等于1.5)使用2倍图  */    background-image: url(img_2x.png);  }}

估计当时应该是320的设计稿,img_1x.png是在320设计稿下切出的图,然后img_2x.png是在320设计稿矢量放大2倍后切出的图,高清屏显示img_2x.png,这样就能解决当时iphone4背景图片模糊的问题。

时至今日,手机都是走高配置,低价格的发展路线,480*800这种级别的机子,市面上越来越少,大部分手机的分辨率级别都达到了iphone4的标准,比iphone4的清晰级别更高的手机也越来越多,一个800块的魅蓝note,它的devicePixelRatio都已经达到了3,原先解决background-image问题的方法,需要调整一下才能适用于现在:

.css{/* 普通显示屏(设备像素比例小于等于2)使用2倍的图 */     background-image: url(img_2x.png);}@media only screen and (-webkit-min-device-pixel-ratio:2.1){.css{/* 高清显示屏(设备像素比例大于等于2.1)使用3倍图  */    background-image: url(img_3x.png);  }}

代码中的2x和3x是相当于320的设计稿而言的,2x代替了原先的1x,3x代替了原先的2x。现在的设计稿也不再是320,而是640,2x就是在640下切出的图,3x是在640基础上矢量放大1.5切出的图。在这个代码的作用下,分辨率在640以下的设备都会显示2x的图,由于2x的图本身是在640的设计稿切出的,所以这些设备下不会有模糊的现象,在640以上的分辨率,会显示3x的图,由于3x的图是在960的分辨率下切出的,所以这种图在分辨率小于960的设备下都不会模糊。以前1x的情况根本不用再考虑了,以后不会再有需要1x图的设备,说不定过几年,市面上的手机全是devicePixelRatio在2.5以上的标准时,连2x的情况也不用考虑了。

lib-flexible在iphone6推出之后,把设计稿的尺寸提高到了750,切图时还是按2x和3x的方法来切,这样的话,经过lib-flexible适配的设备,分辨率在750以下都会显示2x的图,肯定不会模糊;分辨率在750以上的设备,会显示3x的图,也不会出现模糊。不过由于lib-flexible只适配了iphone的问题,所以我上篇博客中提到的用data-dpr来显示不同的图片的做法是错误的,因为有些安卓机,比如我的魅族node,devicePixelRatio是3,打开app页面,看到的图片却仍然还是2x的,显然达不到适配的要求,所以不能用data-dpr去适配,而应该采用下面这个做法:

.retina-image(@background-image) {  background-image: url("../img/@2x/@{background-image}?v=@@version");  background-size: 100% 100%;  background-position:left top;  @media only screen and (-webkit-min-device-pixel-ratio: 2.5),  only screen and (min--moz-device-pixel-ratio: 2.5), /* 注意这里的写法比较特殊 */  only screen and (-o-min-device-pixel-ratio: 5/2),  only screen and (min-device-pixel-ratio: 2.5),  only screen and (min-resolution: 240dpi),  only screen and (min-resolution: 2.5dppx) {    & {      background-image: url("../img/@3x/@{background-image}?v=@@version") !important;    }  }  //1dppx = 1devicePixelRatio, 1dppx = 96dpi.}

这个代码的最终效果是:

1)devicePixelRatio大于等于2.5的设备都会应用到3x图

2)其它设备都会应用到2x的图。

这个方法,在chrome的模拟器里测试过很多机型,效果不错, 不过它只适用于不使用雪碧图的背景图片 ,如果要在lib-flexible的项目里使用雪碧图作背景图片,同时又要考虑retina屏的话,需要将上面这个方法稍微改动一下。

首先看下不使用lib-flexible时,雪碧图背景在retina下是怎么做的,以腾讯的一个活动页面来说明 http://qzs.qq.com/qzone/qzact/act/qzapp/qzone5.0/mobile/index.html ,这是它在使用1x的雪碧图时某个元素的background的样式:

这是它在使用2x的雪碧图时某个元素的background的样式:

总结下它这个做法:

1)先把设计稿切出的图,合并成一张雪碧图,腾讯这个例子的设计稿是320的,所以它的切图都是1x的,这张雪碧图也就是1x的,大小为643 * 152

2)设计稿放大2倍,切图合并成一张2x的雪碧图,大小为1286 * 304

3)普清屏下只应用background-image和background-position属性,设置1x雪碧图作为背景,代码参考截图

4)高清屏下除了应用background-image和background-position属性,还要应用background-size属性,并且这个background-size的大小要设置为1x雪碧图的大小,background-position的值要与(3)里配置的值相同,代码参考截图。

如果把它做成一个mixin的话应该是类似这样的:

.retina-image(@background-image,@background-pos-x,@background-pos-y,@background-size-x,@background-size-y) {  background-image: url("../img/@1x/@{background-image}?v=@@version");  background-position:@background-pos-x @background-pos-y;  @media only screen and (-webkit-min-device-pixel-ratio: 1.25),  only screen and (min-resolution: 120dpi),  only screen and (min-resolution: 1.25dppx) {    & {      background-size: @background-size-x @background-size-y;      background-image: url("../img/@2x/@{background-image}?v=@@version") !important;    }  }  //1dppx = 1devicePixelRatio, 1dppx = 96dpi.}

考虑到1x不会再有的情况,上面这个mixin可以再调整一下:

.retina-image(@background-image,@background-size-x,@background-size-y,@background-pos-x,@background-pos-y) {  background-image: url("../img/@2x/@{background-image}?v=@@version");  background-size: @background-size-x @background-size-y;  background-position:@background-pos-x @background-pos-y;  @media only screen and (-webkit-min-device-pixel-ratio: 2.5),  only screen and (min--moz-device-pixel-ratio: 2.5), /* 注意这里的写法比较特殊 */  only screen and (-o-min-device-pixel-ratio: 5/2),  only screen and (min-device-pixel-ratio: 2.5),  only screen and (min-resolution: 240dpi),  only screen and (min-resolution: 2.5dppx) {    & {      background-image: url("../img/@3x/@{background-image}?v=@@version") !important;    }  }  //1dppx = 1devicePixelRatio, 1dppx = 96dpi.}

默认用2x的图,devicePixelRatio大于等于2.5的设备用3x的图。这个调整后的mixin就是lib-flexible下,使用雪碧图背景的方法,应用举例:

@font-size-base: 75;.btn-android {  .retina-image("sprite.png", 414rem/@font-size-base, 232rem/@font-size-base, 0, -64rem/@font-size-base);}

sprite.png用750设计稿的切图合并后的大小是414 * 232,.btn-android这个按钮的position为0 –64px。

尽管这个方法看起来完美,但是不建议使用,因为它的适配效果不好,这是iphone6下的效果:

看起来不错,那是当然的,因为这就是它默认没有任何缩放的效果。然后看iphone6 plus的效果:

有点差异,但好像还能接受。再看看nexus6的效果:

这就不能忍了,样式差的离谱。造成这个差异的原因也很简单,就是rem的副作用,腾讯的页面里所有position,size都是不带小数的数值,而且2x跟1x之间是整数的翻倍,而不是3x跟2x之间的1.5倍,lib-flexible会导致大部分的设备下position和size都是小数数值,所以很难保证背景图片缩放后还能通过position显示到正确的位置:

从网页优化的角度来说,减少请求数,减少请求数据大小是两个基本的思路,雪碧图就是一个减少请求数但是不能减少请求数据量的方法。lib-flexible不能使用兼容3x屏的雪碧图的情况看起来是它一个大的缺陷,但实际上也并非如此:雪碧图如果用不了,就采用别的思路来优化,我能想到的更好的就是图片的延迟加载和懒加载,在app页面里控制好默认只加载首屏的图片,并且采用延迟和懒加载的方式,避免阻塞页面的加载,也能有极好的用户体验,打开手机淘宝的页面给人的感觉就是如此,而且你去看看手机淘宝的应用会发现它根本就没有用雪碧图,但是速度还是很快。

4. 结束语

本文主要研究了lib-flexible与响应式布局,1px边框和retina屏里背景图片适配的问题,希望能对你使用lib-flexible有所帮助,文中提出的方法不一定是最好的办法,而且可能还有遗漏的情况未考虑到,尤其是最后的背景图片问题,仅仅是webapp里图片处理的一个细小分支,有不对的地方,请您多多指正!

谢谢阅读:)

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。