曲线边框CSS实现

3

最近我在Dribbble上看到了一个设计概念,它真的很启发我。特别是侧边栏顶部和底部带有弯曲的U形,让我对制作标签堆栈或流程图产生了很好的想法。我可以使用alpha图像来制作它,但最好使用纯CSS,我不介意使用CSS3。然而我不熟悉CSS3,希望有人能建议我一种方法来实现它。

you can see a U-shape concavity at the top and a same shape convexity at the buttom

http://dribbble.com/shots/1213195-CMS-Concept/attachments/162177 裁剪

原始设计来自 http://dribbble.com/shots/1213195-CMS-Concept

7个回答

3
我正在使用CSS3的transform属性来倾斜两个伪元素:before:after,它们位于每个彩色部分的顶部。我不得不在绿色下方放置一个桩来显示绿色唇形。
请参见示例 以下是主要的CSS形状:
/* Shape */

.flap {
    display: block;
    position: relative;
}
.flap:before, .flap:after {
    content:'';
    display: block;
    position: absolute;
    top: -2em;
    z-index: 5;
    width: 100%;
    height: 4em;
    border-radius: 1em;
    background-color: inherit;
    border: inherit;
    border-width: 4px;
}
.flap:before {
    left: -50%;
    -webkit-transform: skew(60deg);
    -moz-transform: skew(60deg);
    -o-transform: skew(60deg);
}
.flap:after {
    right: -50%;
    -webkit-transform: skew(-60deg);
    -moz-transform: skew(-60deg);
    -o-transform: skew(-60deg);
}

哇,这真的很接近。我想我可以跟着做一些改进。 - Rix
@Rix。我有一个使用额外圆圈的不太稳定版本,http://jsfiddle.net/yReG5/,可能与您的背景纹理不兼容。想和你分享一下。 - cjross
你给了我一个好建议。我会尝试一下,看看能走多远。 - Rix

3

有很多好的方法 - 我想添加一种不同的方法,并且在所有HTML5浏览器中兼容。

它不像纯CSS解决方案那样直接简洁,但它使用画布生成边框,因此还提供了生成渐变等扩展可能性。

这里是在线演示

其结果如下:

Example

这里是一个简单的例子,展示如何从JavaScript中使用:

该函数需要三个参数:

  1. 要添加边框的元素
  2. 曲线的高度
  3. 背景颜色

例如:

curlyBorder(border1, 24, '#073');
curlyBorder(border2, 24, '#037');

HTML:

<div id="border1">Text 1</div>
<div id="border2">Text 2</div>

CSS:(主要用于定义尺寸和颜色)

#border2 {
    position:relative;
    top:-25px;
}
#border1, #border2 {
    width:300px;
    height:150px;
    padding:30px 16px;
    color:#fff;
    font:26px sans-serif;
    text-align:center;
}

JavaScript:

该函数生成带有图形的画布,并将其设置为元素的背景。代码未经过优化。无论如何,它都可以扩展以支持渐变、更漂亮的边框线等。在这里,我将其保持最小,只是为了举例说明:

function curlyBorder(el, ch, color) {

    var canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');

    render();

    function render() {

        var w = el.clientWidth,
            h = el.clientHeight,
            t = w * 0.333;

        canvas.width = w;
        canvas.height = h;

        /// define border
        ctx.moveTo(0, 0);
        ctx.lineTo(t, 0);

        /// create one curve positive direction
        renderCurve(t, ch, 1);

        ctx.lineTo(w, 0);
        ctx.lineTo(w, h - ch);
        ctx.lineTo(w - t, h - ch);

        /// create one curve negative direction
        renderCurve(t, ch, -1);

        ctx.lineTo(0, h - ch);
        ctx.closePath();

        /// color or gradient
        ctx.fillStyle = color;
        ctx.fill();

        /// set this canvas as background to element
        el.style.background = 'url(' + 
            canvas.toDataURL() + ') no-repeat top left';

        /// we use trigonometry to make the curved line:
        function renderCurve(t, ch, d) {

            var x, sx, ex,dg = -90, dgd = 360 / t, y;

            if (d > 0) {
                x = t;
                for(; x < t * 2; x++) {
                    y = ch * 0.5 * Math.sin(dg * Math.PI / 180);
                    ctx.lineTo(x, y + ch * 0.5);
                    dg += dgd;
                }
            } else {
                x = t * 2;
                for(; x > t; x--) {
                    y = ch * 0.5 * Math.sin(dg * Math.PI / 180);
                    ctx.lineTo(x, h - ch * 0.5 + y);
                    dg += dgd;
                }
            }
        }
    }
}

这样做的缺点是不如CSS高效,但如果只针对少量元素,性能是可以接受的。
您需要调整元素的位置。我使用了硬编码的下一个元素相对位置和偏移量 - 这可以通过其他CSS规则(甚至在函数本身中实现)更好地解决。
但积极的一面是:您在设计可能性方面有更多自由,并且可以更改大小并获得与缩放图像相比更高质量的渲染。
它将在所有支持canvas的HTML5浏览器中呈现相同的效果(我认为甚至IE&lt; 9使用exCanvas也能够呈现此效果,但我没有检查)。

不错的尝试和很棒的外观!虽然在常规网页中我们不经常使用画布,但它可以包含在某些画布应用程序中。 - Rix
哇!这太棒了! :) - Arkana

1
在每个 div 的末尾创建普通边框,然后在 div 的中心位置使用绝对定位放置形状。您可以使用 CSS 3 的 border 属性绘制形状。
.semicirclebottom{
 height:45px;
 width:90px;
 border-radius: 0 0 90px 90px;
 -moz-border-radius: 0 0 90px 90px;
 -webkit-border-radius: 0 0 90px 90px;
 background:green;
 }

 .oval{
 height:180px;
 width:45px;
 border-radius: 90px / 45px;
 -moz-border-radius:90px / 45px;
 -webkit-border-radius: 90px / 45px;
 background:green;
 }

使用曲线三角形可以使其更接近您的要求。
 div {
transform: rotate(45deg);
-ms-transform: rotate(45deg); /* IE 9 */
-webkit-transform: rotate(45deg); /* Safari and Chrome */
-o-transform: rotate(45deg); /* Opera */
-moz-transform: rotate(45deg); /* Firefox */
background-color:green;
width:100px;
height:100px;
position:absolute;
top:20px;
left:-50px;
-webkit-border-radius: 0 20px 0 0;
-moz-border-radius: 0 20px 0 0;
border-radius: 0 20px 0 0;

}


0

很抱歉要传递这个坏消息,但是没有办法实现那种效果。您可以使用:after伪元素制作一个带有圆角的正方形,旋转并定位它,但这是您能够接近的最佳效果,而且看起来仍然不是特别好。

我认为使用图形(图像/SVG)将是最佳解决方案。

编辑:根据Prasanna的想法尝试了一些CSS,这就是我想出的东西。不是最好的,但这是我能够接近的最佳效果。

.main {
    width: 200px;
    height: 200px;
    position: relative;
}
.semicirclebottom{
    height:40px;
    width:80px;
    border-radius: 0 0 90px 90px;
    -moz-border-radius: 0 0 90px 90px;
    -webkit-border-radius: 0 0 90px 90px;
    position: absolute;
    left: 50%;
    margin-left: -40px;
    bottom: -20px;
    z-index: 999999;
 }

.green {
    background: green;
}

.red {
    background: red;
}

http://jsfiddle.net/5gbLB/2/


0

我复制了Prasanna的答案..这是我得到的最接近的答案..

http://jsfiddle.net/P2PEH/

.semicirclebottom{
 margin-right: 100px;
 height:50px;
 width:120px;
 border-radius: 0 0 120px 120px;
 -moz-border-radius: 0 0 120px 120px;
 -webkit-border-radius:  0 0 140px 140px;
 background:green;
margin-left:170px;
 }

.rectangle {    
 height:180px;
width:545px;
 background:green;
}

这种编码方式有点糟糕,我想.. SVG 可以做到很多。但第一张黑色背景平铺图案的图片,我对 SVG 的可行性表示怀疑。


0

请查看 Js fiddle

cjross fiddle 的修改

http://jsfiddle.net/MS5J7/6/

.blue-flap {
    background-color: #4DA0E3;
    border-top: 4px solid #4DA0E3;
}

.green-flap {
    background-color: #65DA83;
    border-top: 4px solid  #65DA83;
}
.brown-flap {
    background-color: #222222;
    border-top: 4px solid #222222;
}

0

这是我的尝试,使用边框、变换和其他内容在:after:before伪元素中实现。

enter image description here

当然,你可以调整值以获得完美的像素结果。 但是我无法重新创建形状下面的小边框或阴影... :/

http://jsfiddle.net/WHvsM/


1
是的,这是一个好方法。也许我可以使用JavaScript动态添加空的div,这样就不会扭曲语义了。 - Rix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接