守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 1608|回复: 0
打印 上一主题 下一主题

[Sass/Scss] 使用Sass制作菱形网格布局

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    52694
    钢镚
    1422

    开源英雄守望者

    跳转到指定楼层
    楼主
    发表于 2016-8-18 16:31:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    来源:http://www.w3cplus.com/preprocessor/diamond-grid-using-sass.html


    自从我从事 WEB 开发以来,一直都在规规矩矩地使用标准的栅格布局。直到有一次在公司跟实习生交流时,我意识到开发者的思维已经被条条框框固定住了。这里并不是想说栅格布局这种规规矩矩的布局有什么不好,实际上这些布局就像是沃尔沃汽车一样,让人感到安稳和可靠。但是,拥抱变化何尝不是一件趣事?非常幸运的是,我能与众多才华横溢的设计师共同工作。在最近的一个项目中,他们提出了一种基于栅格布局的菱形布局。话不多说,迎战问题(•̀o•́)ง!

    旋转 div

    首先,我并没有迅速投入到实际效果的开发中,而是使用 HTML 和 CSS 对脑海中的一些灵感进行验证。第一个浮现在我脑海中的想法就是使用 CSS transforms 来处理这种布局。只是使用 transform: rotate(45deg) 就可以了吗?然而这并没有达到我们想要的效果。设计师提供的效果图由两小、两中、一大五个菱形组成,各个菱形相邻分布,而且稍微改动一下还可以实现反向效果。

    菱形网格

    菱形网格

    我编写的布局标签如下所示:

    <div class="grid-wrapper layout-1">
        <div class="grid-item diamond-small diamond-s1">
            <div class="diamond__content">
                <p>small diamond</p>
            </div>
        </div>
        <div class="grid-item diamond-med diamond-m1">
            <div class="diamond__content">
                <p>medium diamond</p>
            </div>
        </div>
        <div class="grid-item diamond-large">
            <div class="diamond__content">
                <p>large diamond</p>
            </div>
        </div>
        <div class="grid-item diamond-small diamond-s2">
            <div class="diamond__content">
                <p>small diamond</p>
            </div>
        </div>
        <div class="grid-item diamond-med diamond-m2">
            <div class="diamond__content">
                <p>medium diamond</p>
            </div>
        </div>
    </div>
    

    然后我使用 Sass 创建了一些变量,比如创建了一个 grid-unit 来保存栅格单元的尺寸,其中 95vw/16 就是这个栅格单元的尺寸,这个尺寸并没有太多深意,在这里只是用于演示效果:

    $gridUnit: 95vw / 16;
    $small: $gridUnit * 2;
    $med: $gridUnit * 3;
    $large: $gridUnit * 4;
    

    看到这里,相信聪明的你已经猜到了这种方法决不能创建我们需要的布局,因为当我们旋转时,所有的标签是以自身为中心进行旋转的,最终我们看到的效果就是这样:

    菱形网格

    菱形网格

    裁剪 div

    我的第二个想法是使用 CSS clip-path,该属性允许开发者隐藏元素的特定区域,所有超过该区域的内容都不会被裁减掉。要创建裁剪区域,需要引用 SVG 的路径,或者使用类似于 CSS shapes 中用到的塑形方法(shape method)。不幸的是,任何版本的 IE 浏览器都不支持 CSS clip-path,Firefox 只支持 url() 引用 SVG 的方式,而 Chrome 不支持使用 url() 引用外部 SVG 的方式。所以,我找到了一个用于 CSS clip-path 的脚本(ployfill),用于解决浏览器的不支持问题。

    该想法的实质就是裁剪掉正方形的边角模拟出菱形来,而正方形的边长正好是菱形对角线的长度,稍微加工一下,效果如下:

    此时,看起来我已经实现了设计师想要的那种效果,但是实际上还缺少了一些视觉效果。我可以假设它的背景就是菱形栅格,然后使用 CSS 来模拟实现。如果所有的菱形栅格都是相同尺寸的菱形,那就更容易了。稍作修饰,效果如下:

    然后我仔细查看了设计师提供的设计图。简而言之,这个菱形布局是用于偏向于图片展示的网站,上面将会有大量的图片,而且每个栅格单元的背景具有一定的纹理。此外,为了突出显示某些菱形,需要为它们的边角添加一些高亮效果。那么,我们可以给这些需要突出显示的菱形添加一些内阴影。

    中学数学的救赎

    因为这里的菱形可以看成是由正方形旋转之后得到的,所有可知图示的三角形 AOH 为等腰直角三角形:

    菱形网格

    由中学数学知识可以,在等腰直角三角形中,斜边除以 Math.sqrt(2) 等于直角边,所以我使用 Sass 写了一个 @function 来计算 Math.sqrt(2)

    @function sqrt($r) {
        $x0: 1;
        $x1: $x0;
        @for $i from 1 through 10 {
            $x1: $x0 - ($x0 * $x0 - abs($r)) / (2 * $x0);
            $x0: $x1;
        }
        @return $x1;
    }
    $gridUnit: (100vw / 8);
    $transformUnit: $gridUnit / sqrt(2);
    $small: $transformUnit * 2;
    $med: $transformUnit * 3;
    $large: $transformUnit * 4;
    

    现在我还没有想出让每一个菱形绝对定位的方式,如果你有什么建议欢迎交流。我已经尽力结构化标签上的类名了,如果时间允许,我想我会尽可能多地去尝试不同的方式。现在,根据之前创建的栅格单元确定大小和位置是最大的一个活了,幸亏 Sass 的帮助我才能这么顺利地搞定这项工作:

    视觉优化

    使用 CSS 旋转 div,可以让需要突出显示的菱形拥有内阴影。对于菱形的背景,我使用了纹理图片,然后微调了 div 的对齐方式以贴合纹理图片。因为我是用了 viewport width(vw) 作为栅格单元的长度单位,所以布局效果时响应式,然而,这种方式的缺点在于背景的纹理图片也会根据视图宽度收缩或拉伸。

    解决这一问题的方法就是让背景图片非常精确地贴合相应的栅格,但实际上由于屏幕尺寸多种多样很难实现尺寸的精准贴合。在大尺寸的屏幕上 1 像素的缺失都会非常显眼。因为我所做的项目并非整体都是响应式的,所有并没有遇到这样的问题:

    body {
        @media screen and (min-width: 1000px) and (max-width: 1919px) {
            background: url('../img/bg-tile.jpg') repeat-y;
            background-size: contain;
        }
    }
    

    这里的技巧就是使用 background-size: contain 来设置背景图片。根据 MDN 的资料,浏览器会自动伸缩图片保持屏宽比。虽然我尽力让背景和 Sass 的栅格单元尺寸保持一致,但总有一两个像素的差异。好在这些差异在我的项目中并不明显。高亮效果使用了 :before 和 :after 伪元素,同时使用了 Sass 栅格单元的尺寸来定位到正确的位置。

    总结

    这是一个有趣的项目,视野和技能方面都有所收获。在这个项目中还有很多值得思考的地方,但是布局效果是其他设计效果的基础。CSS 属性中的 clip-path/transform/css shapes,为我们提供了足够的灵活性去探索不同的布局。在我开发这个项目的同时,Trevor Davis 同样实现了一个菱形布局。我们正在突破现有的布局桎梏,相信未来 CSS 将会更加健壮,我们可以创建更富有创造性的设计效果。

    本文根据@Hui Jing的《Diamond grid layout with Sass》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://www.chenhuijing.com/blog/diamond-grid-using-sass/

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
    收藏收藏 分享分享 支持支持 反对反对 微信
    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2024-4-20 02:12 , Processed in 0.053539 second(s), 36 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表