V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
selfcreditgiving
V2EX  ›  问与答

请问 css 这样的异形布局,大家一般是怎么实现的?

  •  
  •   selfcreditgiving · 2019-08-28 21:02:58 +08:00 · 3126 次点击
    这是一个创建于 1920 天前的主题,其中的信息可能已经有所发展或是发生改变。

    下图是现在做出来的效果。
    主要是那 4 个斜边,我知道 border 法可以画出三角形,可是因为斜边是带边框的,目前的方法用的是 border 法画出内外两三角形,内面三角形的颜色是背景色,外面三角形的颜色是边框色,然后让两个三角形平着错开,错开的宽度等于边框的宽度(这里是 2px )

    觉得还是有点麻烦,请问各位大佬有什么更佳的实现吗。

    异形布局

    这是 Vue 的代码:

    <template lang="html">
    <div class="wrap">
    
        <div id="top-1"></div>
        <div id="left-1"></div>
        <div id="left-2"></div>
        <div id="left-3"></div>
        <div id="left-3-tri-out"></div>
        <div id="left-3-tri-in"></div>
        <div id="left-4"></div>
        <div id="left-5"></div>
        <div id="left-6"></div>
        <div id="left-7"></div>
        <div id="left-7-tri-out"></div>
        <div id="left-7-tri-in"></div>
        <div id="right-1"></div>
        <div id="right-2"></div>
        <div id="right-3"></div>
        <div id="right-3-tri-out"></div>
        <div id="right-3-tri-in"></div>
        <div id="right-4"></div>
        <div id="right-5"></div>
        <div id="right-6"></div>
        <div id="right-7"></div>
        <div id="right-7-tri-out"></div>
        <div id="right-7-tri-in"></div>
    </div>
    </template>
    
    <script>
    import base from '../common/js/base';
    
    export default {
    
    }
    
    </script>
    
    <style lang="scss" scoped>
    @import '~@/common/css/base.scss';
    
    // 使用 vw 转化成和设计稿一样的尺寸
    $ui-width: 1920px;
    @function px2vw($px) {
        @return $px / $ui-width * 100vw;
    }
    
    $color-border: #2F55A4;
    
    * {
        box-sizing: content-box;
    }
    .wrap {
        background-color: $navMenuBackColor;
        height:px2vw(1080px);
        width: px2vw(1920px);
    }
    #top-1 {
        position: absolute;
        left: px2vw(460px);
        width: px2vw(1000px);
        height: px2vw(153px);
        background: $navMenuBackColor;
        box-sizing: border-box;
        border-bottom: px2vw(1px) solid $color-border;
    }
    #left-1 {
        position: absolute;
        left: px2vw(0px);
        width: px2vw(459px);
        height: px2vw(106px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
        border-right: px2vw(1px) solid $color-border;
    }
    #left-2 {
        position: absolute;
        left: px2vw(0px);
        top: px2vw(108px);
        width: px2vw(459px);
        height: px2vw(43px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
        border-right: px2vw(1px) solid $color-border;
    }
    #left-3 {
        position: absolute;
        left: px2vw(0px);
        top: px2vw(153px);
        width: px2vw(362px);
        height: px2vw(292px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
    }
    #left-3-tri-out {
        position: absolute;
        left: px2vw(362px);
        top: px2vw(153px);
        width: px2vw(0px);
        height: px2vw(0px);
        border-top: px2vw(294px) solid $color-border;
        border-right: px2vw(98px) solid transparent;
    }
    #left-3-tri-in {
        position: absolute;
        left: px2vw(360px);
        top: px2vw(153px);
        width: px2vw(0px);
        height: px2vw(0px);
        border-top: px2vw(294px) solid $navMenuBackColor;
        border-right: px2vw(98px) solid transparent;
    }
    #left-4 {
        position: absolute;
        left: px2vw(0px);
        top: px2vw(447px);
        width: px2vw(362px);
        height: px2vw(43px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
        border-right: px2vw(2px) solid $color-border;
    }
    #left-5 {
        position: absolute;
        left: px2vw(0px);
        top: px2vw(492px);
        width: px2vw(362px);
        height: px2vw(266px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
        border-right: px2vw(2px) solid $color-border;
    }
    #left-6 {
        position: absolute;
        left: px2vw(0px);
        top: px2vw(760px);
        width: px2vw(362px);
        height: px2vw(43px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
        border-right: px2vw(2px) solid $color-border;
    }
    #left-7 {
        position: absolute;
        left: px2vw(0px);
        top: px2vw(805px);
        width: px2vw(362px);
        height: px2vw(275px);
        background: $navMenuBackColor;
    }
    #left-7-tri-out {
        position: absolute;
        left: px2vw(362px);
        top: px2vw(805px);
        width: px2vw(0px);
        height: px2vw(0px);
        border-bottom: px2vw(275px) solid $color-border;
        border-right: px2vw(98px) solid transparent;
    }
    #left-7-tri-in {
        position: absolute;
        left: px2vw(360px);
        top: px2vw(805px);
        width: px2vw(0px);
        height: px2vw(0px);
        border-bottom: px2vw(275px) solid $navMenuBackColor;
        border-right: px2vw(98px) solid transparent;
    }
    #right-1 {
        position: absolute;
        right: px2vw(0px);
        width: px2vw(459px);
        height: px2vw(106px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
        border-left: px2vw(1px) solid $color-border;
    }
    #right-2 {
        position: absolute;
        right: px2vw(0px);
        top: px2vw(108px);
        width: px2vw(459px);
        height: px2vw(43px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
        border-left: px2vw(1px) solid $color-border;
    }
    #right-3 {
        position: absolute;
        right: px2vw(0px);
        top: px2vw(153px);
        width: px2vw(362px);
        height: px2vw(292px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
    }
    #right-3-tri-out {
        position: absolute;
        right: px2vw(362px);
        top: px2vw(153px);
        width: px2vw(0px);
        height: px2vw(0px);
        border-top: px2vw(294px) solid $color-border;
        border-left: px2vw(98px) solid transparent;
    }
    #right-3-tri-in {
        position: absolute;
        right: px2vw(360px);
        top: px2vw(153px);
        width: px2vw(0px);
        height: px2vw(0px);
        border-top: px2vw(294px) solid $navMenuBackColor;
        border-left: px2vw(98px) solid transparent;
    }
    #right-4 {
        position: absolute;
        right: px2vw(0px);
        top: px2vw(447px);
        width: px2vw(362px);
        height: px2vw(43px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
        border-left: px2vw(2px) solid $color-border;
    }
    #right-5 {
        position: absolute;
        right: px2vw(0px);
        top: px2vw(492px);
        width: px2vw(362px);
        height: px2vw(266px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
        border-left: px2vw(2px) solid $color-border;
    }
    #right-6 {
        position: absolute;
        right: px2vw(0px);
        top: px2vw(760px);
        width: px2vw(362px);
        height: px2vw(43px);
        background: $navMenuBackColor;
        border-bottom: px2vw(2px) solid $color-border;
        border-left: px2vw(2px) solid $color-border;
    }
    #right-7 {
        position: absolute;
        right: px2vw(0px);
        top: px2vw(805px);
        width: px2vw(362px);
        height: px2vw(275px);
        background: $navMenuBackColor;
    }
    #right-7-tri-out {
        position: absolute;
        right: px2vw(362px);
        top: px2vw(805px);
        width: px2vw(0px);
        height: px2vw(0px);
        border-bottom: px2vw(275px) solid $color-border;
        border-left: px2vw(98px) solid transparent;
    }
    #right-7-tri-in {
        position: absolute;
        right: px2vw(360px);
        top: px2vw(805px);
        width: px2vw(0px);
        height: px2vw(0px);
        border-bottom: px2vw(275px) solid $navMenuBackColor;
        border-left: px2vw(98px) solid transparent;
    }
    
    </style>
    
    
    
    19 条回复    2019-08-30 09:48:41 +08:00
    rabbbit
        1
    rabbbit  
       2019-08-28 21:20:20 +08:00
    svg 背景
    TangMonk
        2
    TangMonk  
       2019-08-28 21:35:24 +08:00
    Photoshop 好像可以画好了导出到 svg,不用写代码的。
    Phuasheng
        3
    Phuasheng  
       2019-08-28 21:39:50 +08:00
    为啥不用 js ?
    learnshare
        4
    learnshare  
       2019-08-28 21:40:41 +08:00
    绘图自然不应该是用布局写,SVG 或者 Canvas 绘制吧
    TangMonk
        5
    TangMonk  
       2019-08-28 21:55:45 +08:00
    原来是布局,理解错了
    POPOEVER
        6
    POPOEVER  
       2019-08-28 22:20:41 +08:00
    这是做游戏界面?
    kvsico
        7
    kvsico  
       2019-08-28 22:36:18 +08:00 via Android
    ae 几分钟搞定
    shintendo
        8
    shintendo  
       2019-08-28 22:37:11 +08:00
    @POPOEVER 目测数据大屏 XD
    AlphaTr
        9
    AlphaTr  
       2019-08-28 22:38:43 +08:00 via iPhone
    background svg path 来做
    AlphaTr
        10
    AlphaTr  
       2019-08-28 22:59:08 +08:00
    大概手写是这样子的,参数随意调整:background: url('data:image/svg+xml;utf8,<svg height="400" viewBox="0 0 200 200" width="400" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke-width="1" stroke="red"><path d="m200,0h-200l0,200h160z"/></g></svg>')
    murmur
        11
    murmur  
       2019-08-28 23:17:21 +08:00
    贴图 png 或者 svg 都可以 这么复杂就不要考虑自己画了
    sunjourney
        12
    sunjourney  
       2019-08-29 09:09:57 +08:00
    这和 vue 有什么关系
    TomVista
        13
    TomVista  
       2019-08-29 09:33:35 +08:00
    https://www.w3cplus.com/css3/css-shapes-breaking-rectangular-design.html
    https://juejin.im/entry/578f21ccc4c971005e0d90a6

    从收藏夹里扒拉醋来的,你看看,主要是 clip-path masking CSS Shapes ,对浏览器兼容不大友好,有好的方案记得 @我
    fxy739371
        14
    fxy739371  
       2019-08-29 10:20:23 +08:00
    react 几分钟搞定
    lllllliu
        15
    lllllliu  
       2019-08-29 10:29:07 +08:00
    Svg,Canvas,png+1 背景层一个节点就搞定的事情不需要这么麻烦
    TomVista
        16
    TomVista  
       2019-08-29 17:18:22 +08:00
    @lllllliu 你说的那个方法,三角区域能放东西吗?![Image Pasted at 2019-8-28 20-41.png]( https://i.loli.net/2019/08/29/w1SrHk9V5e8fdtv.png)
    lllllliu
        17
    lllllliu  
       2019-08-30 09:24:55 +08:00   ❤️ 1
    @TomVista 可以的呀。除了 png 其他两种都是画,可以随便画你想要的。0.0 甚至你的数据大屏都可以用 canvas 来做。如果交互比较弱。这样可以用一些游戏引擎搞得很炫酷~~。
    selfcreditgiving
        18
    selfcreditgiving  
    OP
       2019-08-30 09:41:27 +08:00
    @lllllliu 哈哈 还有这种思路。这个页面两边都是 chart 图表,中间是一个大的地图,要求就是越炫酷越好 :)
    lllllliu
        19
    lllllliu  
       2019-08-30 09:48:41 +08:00
    @selfcreditgiving 我之前用过 cocos create 做过一次。用过 tree+d3 也搞过一次,不过还是喜欢用游戏引擎做这种炫酷的东西。。因为很多效果都是现成的。反正都是 js
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1118 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:24 · PVG 07:24 · LAX 15:24 · JFK 18:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.