形状有斜边(响应) [英] Shape with a slanted side (responsive)
问题描述
我尝试在下面的图片中创建一个形状,只在一侧有倾斜边缘(例如底边),而其他边缘保持笔直。
我尝试使用border方法(代码如下),但是我的形状的尺寸是动态的,因此我不能使用这个方法。
.shape {position:relative; height:100px; width:200px; background:tomato;}。shape:after {position:absolute; content:''; height:0px; width:0px; left:0px; bottom:-100px; border-width:50px 100px; border-style:solid; border-color:tomato tomato transparent transparent;}
div class =shape>部分内容< / div>
我也尝试过使用渐变作为背景(如下面的代码),但它随着尺寸的变化而变得混乱。
.gradient {display:inline-block; vertical-align:top; height:200px; width:100px; margin:10px;颜色:米色; transition:all 1s; padding:10px;背景:线性渐变(45度,透明45%,番茄45%)无重复;}渐变:hover {width:200px;}
< div class =gradient>< / div>
div>
如何创建带斜边的形状,并且还能够支持动态尺寸?
有很多方法只在一边创建带有斜边的形状。
以下方法不能支持问题中已提到的动态尺寸:
- 具有
border-width
像素值的边框三角形法。 - 使用角度语法的线性渐变(例如45deg,30deg等)。
可支持动态大小的方法如下所述。
方法1 - SVG
(浏览器兼容性)
SVG可用于使用 polygon
s或 path
s。下面的代码段使用 polygon
。
$(document).ready(function $('#increasew-vector')。on('click',function(){$('vector')。css({'width':'150px','height':'100px'}) ); $('#increaseh-vector')。on('click',function(){$('。vector')。css({'width':'100px','height':'150px'}) ;}); $('#increaseb-vector')。on('click',function(){$('。vector')。css({'width':'150px','height':'150px' });});})
div {float:剩下; height:100px; width:100px; margin:20px;颜色:米色; transition:all 1s;}。vector {position:relative;} svg {position:absolute; margin:10px; top:0px; left:0px;高度:100%; width:100%; z-index:0;} polygon {fill:tomato;}。 span {position:absolute;显示:block; padding:10px; z-index:1;}。vector.top> span {height:50%; width:100%; top:calc(40%+ 5px); / *有角度区域的大小+缓冲区* /左:5px; } .vector.bottom> span {height:50%; width:100%; top:5px; left:5px; } .vector.left> span {width:50%;高度:100%;左:50%; / *有角度区域的大小* / top:5px; } .vector.right> span {width:50%;高度:100%; left:5px; top:5px; } / *仅用于demo * / body {background:radial-gradient(circle at 50%50%,aliceblue,steelblue);} polygon:hover,span:hover + svg> polygon {fill:steelblue;}。btn-container {position:absolute; top:0px; right:0px; width:150px;} button {width:150px; margin-bottom:10px;}。vector.left {clear:both;}
< script src =https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js>< / script>< script src = https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js\"> ;</script> ;<div class =vector bottom> < span>一些内容< / span> < svg viewBox =0 0 40 100preserveAspectRatio =none> < polygon points =0,0 40,0 40,100 0,60/> < / svg>< / div>< div class =vector top> < span>一些内容< / span> < svg viewBox =0 0 40 100preserveAspectRatio =none> < polygon points =0,40 40,0 40,100 0,100/> < / svg>< / div>< div class =vector left> < span>一些内容< / span> < svg viewBox =0 0 40 100preserveAspectRatio =none> < polygon points =0,0 40,0 40,100 20,100/> < / svg>< / div>< div class =vector right> < span>一些内容< / span> < svg viewBox =0 0 40 100preserveAspectRatio =none> < polygon points =0,0 20,0 40,100 0,100/> < / svg>< / div>< div class ='btn-container'> < button id =increaseasew-vector>增加宽度< / button> < button id =increaseh-vector>增加高度< / button> < button id =increaseb-vector>增加两个< / button>< / div>
优点
- SVG旨在产生可扩展的图形,
- 边框和悬停效果可以通过最小的编码开销实现。
- 图片或渐变背景也可以提供给形状。
缺点
- 浏览器支持可能是唯一的缺点,因为IE8-不支持SVG,但可以通过使用Raphael和VML。此外,浏览器支持绝不比其他选项差。
方法2 - 渐变背景
(浏览器兼容性)
线性渐变仍然可以用于产生形状,但不能用于问题中提到的角度。我们必须使用到[side] [side]
语法(感谢 vals ),而不是指定角度。当指定边时,会根据容器的尺寸自动调整渐变角度。
$(document).ready function(){$('#increasew-gradient')。on('click',function(){$('。gradient')。css({'height':'100px','width':'150px' {'height':'150px','width':'');});} 100px'});}); $('#increaseb-gradient')。on('click',function(){$('。gradient')。css({'height':'150px','width' :'150px'});});})
div {float:left; height:100px; width:100px; margin:10px 20px;颜色:米色; transition:all 1s;}。gradient {position:relative;} gradient.bottom {background:linear-gradient(向右上,透明50%,番茄50%)无重复,线性梯度0.1%,番茄0.1%)无重复;背景尺寸:100%40%,100%60%;背景位置:0%100%,0%0%;}。梯度:背景:线性梯度(右下,透明50%,番茄50%透明0.1%,番茄0.1%)无重复;背景尺寸:100%40%,100%60%;背景位置:0%0%,0%100%;}。gradient.left {背景:线性梯度(右上,透明50%,番茄50%透明0.1%,番茄0.1%)无重复;背景尺寸:40%100%,60%100%;背景位置:0%0%,100%0%;}。gradient.right {背景:线性梯度(至左上,透明50%,番茄50%透明0.1%,番茄0.1%)无重复;背景尺寸:40%100%,60%100%;背景位置:100%0%,0%0%;}渐变跨度{position:absolute;} gradient.top span {top:calc(40%+ 5px); / * background size + buffer * / left:5px; height:50%;}。gradient.bottom span {top:5px; left:5px; height:50%;}。gradient.left span {left:40%; / * background size * / top:5px; width:50%;}。gradient.right span {left:5px; top:5px; width:50%;} / *仅用于演示* / body {background:radial-gradient(circle at 50%50%,aliceblue,steelblue);}。 top:0px; right:0px; width:150px;} button {width:150px; margin-bottom:10px;}。gradient.left {clear:both;}
< script src =https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js>< / script>< script src = https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js\"> ;</script><div class =gradient bottom>< span>部分内容; / span>< / div>< div class =gradient left>< span>部分内容< / span>< / div>< div class ='btn-container'>一些内容< / span>< / div>< div class =gradient right>< < button id =increaseasew-gradient>增加宽度< / button> < button id =increaseh-gradient>增加高度< / button> < button id =increaseb-gradient>增加两个< / button>< / div>
优点
- 即使尺寸的容器是动态的。
- 悬停效果可以通过更改渐变颜色添加。
/ strong>
- 即使光标在形状之外但在容器内,鼠标悬停效果也会被触发。
- 添加边框需要进行棘手的渐变操作。
- 渐变是已知的,当宽度(或高度)非常大时,会产生锯齿形的角。
- 图片背景不能用于形状。
$ b b
方法3 - 倾斜变换
(浏览器兼容性 )
在这种方法中,伪元素被添加,倾斜和定位,使得它看起来像边缘之一是倾斜/有角度的。如果顶部或底边倾斜,歪斜应沿Y轴,否则旋转应沿X轴。 transform-origin
应该与斜边相对。
$(document).ready(function(){$('#increasew-skew')。on('click',function(){$('。skew')。css({'height':' 100px','width':'150px'});}); $('#increaseh-skew')。on('click',function(){$('。skew')。css :'150px','width':'100px'});}); $('#increaseb-skew')。on('click',function(){$('。skew')。css height':'150px','width':'150px'});});})
div {float:left; height:100px; width:100px; margin:50px;颜色:米色; transition:all 1s;}。skew {padding:10px;位置:相对; background:tomato;}。skew:after {position:absolute; content:'';背景:inherit; z-index:-1;}。skew.bottom:after,.skew.top:after {width:100%; height:60%;}。skew.left:after,.skew.right:after {height:100%; width:60%;}。skew.bottom:after {bottom:0px; left:0px; transform-origin:top left; transform:skewY(22deg);}。skew.top:after {top:0px; left:0px; transform-origin:top left; transform:skewY(-22deg);}。skew.left:after {top:0px; left:0px; transform-origin:left left; transform:skewX(22deg);}。skew.right:after {top:0px; right:0px; transform-origin:bottom right; transform:skewX(-22deg);}。skew:hover {background:steelblue;} / *只是用于演示* / body {background:radial-gradient(circle at 50%50%,aliceblue,steelblue);}。 bottom {margin-top:10px;}。skew.left {clear:both;}。btn-container {position:absolute; top:0px; right:0px; width:150px;} button {width:150px; margin-bottom:10px;}
< script src = https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js\"> ;</script> ;<script src =https://ajax.googleapis.com/ ajax / libs / jquery / 2.1.1 / jquery.min.js>< / script>< div class =skew bottom>一些内容< / div>< div class =skew top> ;一些内容< / div>< div class =skew left>部分内容< / div>< div class =skew right>部分内容< / div>< div class ='btn-container '> < button id =increaseasew-skew>增加宽度< / button> < button id =increaseh-skew>增加高度< / button> < button id =increaseb-skew>增加两个< / button>< / div>
b
$ b
优点
- 形状可以通过边框实现。
- 悬停效果将限制在形状内。
strong>
- 维度需要按比例增加要保留的形状,因为当元素歪斜时,其在Y轴上的偏移
width
增加,反之亦然(尝试将宽度
增加到200px
)。您可以在此此处找到更多信息。
方法4 - 透视转换
在此方法中,主容器被旋转沿着X或Y轴有一点透视。将适当的值设置为 transform-origin
将只在一侧产生倾斜边。
如果顶部或底部倾斜,则旋转应沿Y轴旋转,否则旋转应沿X轴旋转。 transform-origin
应该与斜边相对。
$(document).ready(function(){$('#increasew-rotate')。on('click',function(){$(' 100px','width':'150px'});}); $('#increaseh-rotate')。on('click',function(){$('。rotate')。css :'150px','width':'100px'});}); $('#increaseb-rotate')。on('click',function(){$('。rotate')。css height':'150px','width':'150px'});});})
div {float:left; height:100px; width:100px; margin:50px;颜色:米色; transition:all 1s;}。rotate {position:relative; width:100px; background:tomato;}。rotate.bottom {transform-origin:top; transform:perspective(10px)rotateY(-2deg);}。rotate.top {transform-origin:bottom; transform:perspective(10px)rotateY(-2deg);}。rotate.left {transform-origin:right; transform:perspective(10px)rotateX(-2deg);}。rotate.right {transform-origin:left; transform:perspective(10px)rotateX(-2deg);}。rotate span {position:absolute;显示:block; top:0px; right:0px; width:50%; height:100%;}。rotate.bottom span {padding:10px; transform-origin:top; transform:perspective(10px)rotateY(2deg);}。rotate.top span {padding:20px; transform-origin:bottom; transform:perspective(20px)rotateY(2deg);}。rotate.left span {padding:10px; transform-origin:right; transform:perspective(10px)rotateX(2deg);}。rotate.right span {padding:0px 30px; transform-origin:left; transform:perspective(10px)rotateX(2deg);}。rotate:hover {background:steelblue;} / *只是为了演示* / body {background:radial-gradient(circle 50%,aliceblue,steelblue) .rotate.left {clear:both;}。btn-container {position:absolute; top:0px; right:0px; width:150px;} button {width:150px; margin-bottom:10px;}
< script src = https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js\"> ;</script> ;<script src =https://ajax.googleapis.com/ ajax / libs / jquery / 2.1.1 / jquery.min.js>< / script>< div class =rotate bottom>< span>部分内容< / span>< / div>< ; div class =rotate top>< span>部分内容< / span>< / div>< div class =rotate left>< ;< div class =rotate right>< span>部分内容< / span>< / div>< div class ='btn-container'> < button id =increaseasew-rotate>增加宽度< / button> < button id =increaseh-rotate>增加高度< / button> < button id =increaseb-rotate>增加两个< / button>< / div>
b
$ b
优点
- 形状可以通过边框实现。
- 尺寸无需按比例增加要保留的形状。
- 内容也将被旋转,因此它们必须反向旋转才能正常显示。
- 如果尺寸不是静态的,则定位文本将很乏味。
方法5 - CSS剪辑路径
(浏览器兼容性)
在此方法中,主容器使用多边形剪切为所需的形状。
$(document).ready function(){$('#increasew-clip')。on('click',function(){$('clip-path')。css({'height':'100px','width':' 150px'});}); $('#increaseh-clip')。on('click',function(){$('clip-path')。css({'height':'150px',' width':'100px'});}); $('#increaseb-clip')。on('click',function(){$ 150px','width':'150px'});});})
.clip-path {position:relative; float:left; margin:20px; height:100px; width:100px;背景:番茄; padding:4px; transition:all 1s;} clip-path.bottom {-webkit-clip-path:polygon(0%0%,100%0%,100%100%,0%60%);} clip-path.top {-webkit-clip-path:polygon(0%40%,100%0%,100%100%,0%100%);} clip-path.left {-webkit-clip-path: 0%,100%0%,100%100%,40%100%); clip-path.right {-webkit-clip-path: ,0%100%);}。clip-path .content {position:absolute; content:''; height:calc(100% - 10px); width:calc(100% - 8px); background:bisque;} clip-path.bottom .content {-webkit-clip-path:polygon(0%0%,100%0%,100%100%,0%60%);}。 top .content {-webkit-clip-path:polygon(0%40%,100%0%,100%100%,0%100%);}。clip-path .content.img {top:6px; background:url(http://lorempixel.com/250/250); background-size:100%100%;} / *仅适用于演示* / body {background:radial-gradient(circle at 50%50%,aliceblue,steelblue);}。clip-path.left {clear:both;} .clip-path:hover {background:gold;}。btn-container {position:absolute; top:0px; right:0px; margin:20px; width:150px;} button {width:150px; margin-bottom:10px;}
< script src = https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js\"> ;</script> ;<script src =https://ajax.googleapis.com/ ajax / libs / jquery / 2.1.1 / jquery.min.js>< / script>< div class =clip-path bottom> < div class =content> abcd< / div>< / div>< div class =clip-path top> < div class =content img>< / div>< / div>< div class =clip-path left>< / div>< div class =clip-path right >< / div>< div class ='btn-container'> < button id =increaseasew-clip>增加宽度< / button> < button id =increaseh-clip>增加高度< / button> < button id =increaseb-clip>增加两个< / button>< / div>
b
$ b
优点
- 即使容器调整大小动态。
- 悬停效果将完全限制在形状的边框内。
- 图片也可用作形状的背景。
缺点
- 目前支持非常差。
- 可以通过在形状顶部放置一个绝对定位的元素并赋予其必要的剪辑来添加边框,但超出了它在动态调整大小时不适合的点。 li>
方法6 - Canvas
(浏览器兼容性)
Canvas也可用于制作通过绘制路径的形状。下面的代码片段有一个demo。
window.onload = function(){var canvasEls = document.getElementsByTagName('canvas'); for(var i = 0; i
.container {float:left;位置:相对; height:100px; width:100px; margin:20px;颜色:米色; transition:all 1s;} canvas {height:100%; width:100%;}。container> span {position:absolute; top:5px; left:5px; padding:5px;}。top + span {top:40%; / *角度区域的大小* /}。left + span {left:40%; / *角度区域的大小* /} / *仅用于演示* / body {background:radial-gradient(circle at 50%50%,aliceblue,steelblue);}。btn-container {position:absolute; top:0px; right:0px; width:150px;} button {width:150px; margin-bottom:10px;} div:nth-of-type(3){clear:both;}
< script src =https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js>< / script> < script src =https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js>< / script>< div class =container> < canvas height =100pxwidth =250pxclass =bottom>< / canvas> < span>一些内容< / span>< / div>< div class =container> < canvas height =100pxwidth =250pxclass =top>< / canvas> < span>一些内容< / span>< / div>< div class =container> < canvas height =100pxwidth =250pxclass =left>< / canvas> < span>一些内容< / span>< / div>< div class =container> < canvas height =100pxwidth =250pxclass =right>< / canvas> < span>一些内容< / span>< / div>< div class ='btn-container'> < button id =increaseasew-canvas>增加宽度< / button> < button id =increaseh-canvas>增加高度< / button> <按钮ID =increaseb画布>同时增加< /按钮>< / DIV>
赞成
- 形状可实现和保持,即使尺寸的容器是动态的。 c / c>方法。鼠标悬停效果可以通过使用
pointInpath
方法限制在形状的边界内。 - 也可以为图形提供图像或渐变背景。
- 如果需要实时动画效果, DOM操作。
缺点
- 画布是基于光栅的,因此当缩放超过点 * 时,有角边缘将变为像素化或模糊。
* - 每当调整视口大小时,避免像素化都需要重新绘制形状。还有就是它的一个例子href=\"http://jsfiddle.net/hari_shanx/onco0xmk/1/\"> 但是这是一个开销。
I am trying to create a shape like in the image below with a slanted edge on only one side (for example, the bottom side) while the other edges remain straight.
I tried using the border method (code is given below) but the dimensions of my shape are dynamic and hence I cannot use this method.
.shape {
position: relative;
height: 100px;
width: 200px;
background: tomato;
}
.shape:after {
position: absolute;
content: '';
height: 0px;
width: 0px;
left: 0px;
bottom: -100px;
border-width: 50px 100px;
border-style: solid;
border-color: tomato tomato transparent transparent;
}
<div class="shape">Some content</div>
I have also tried using gradients for background (like in the below code) but it gets messed up as the dimensions change. You can see what I mean by hovering on the shape in the below snippet.
.gradient {
display: inline-block;
vertical-align: top;
height: 200px;
width: 100px;
margin: 10px;
color: beige;
transition: all 1s;
padding: 10px;
background: linear-gradient(45deg, transparent 45%, tomato 45%) no-repeat;
}
.gradient:hover {
width: 200px;
}
<div class="gradient"></div>
How can I create this shape with a slanted side and also be able to support dynamic sizes?
There are many ways to create the shape with a slanted edge only on one side.
The following methods cannot support dynamic sizes as already mentioned in the question:
- Border triangle method with pixel values for
border-width
. - Linear gradients with the angle syntax (like 45deg, 30deg etc).
The methods that can support dynamic sizes are described below.
Method 1 - SVG
SVG can be used to produce the shape either by using polygon
s or path
s. The below snippet makes use of polygon
. Any text content required can be positioned on top of the shape.
$(document).ready(function() {
$('#increasew-vector').on('click', function() {
$('.vector').css({
'width': '150px',
'height': '100px'
});
});
$('#increaseh-vector').on('click', function() {
$('.vector').css({
'width': '100px',
'height': '150px'
});
});
$('#increaseb-vector').on('click', function() {
$('.vector').css({
'width': '150px',
'height': '150px'
});
});
})
div {
float: left;
height: 100px;
width: 100px;
margin: 20px;
color: beige;
transition: all 1s;
}
.vector {
position: relative;
}
svg {
position: absolute;
margin: 10px;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
z-index: 0;
}
polygon {
fill: tomato;
}
.vector > span {
position: absolute;
display: block;
padding: 10px;
z-index: 1;
}
.vector.top > span{
height: 50%;
width: 100%;
top: calc(40% + 5px); /* size of the angled area + buffer */
left: 5px;
}
.vector.bottom > span{
height: 50%;
width: 100%;
top: 5px;
left: 5px;
}
.vector.left > span{
width: 50%;
height: 100%;
left: 50%; /* size of the angled area */
top: 5px;
}
.vector.right > span{
width: 50%;
height: 100%;
left: 5px;
top: 5px;
}
/* Just for demo */
body {
background: radial-gradient(circle at 50% 50%, aliceblue, steelblue);
}
polygon:hover, span:hover + svg > polygon{
fill: steelblue;
}
.btn-container {
position: absolute;
top: 0px;
right: 0px;
width: 150px;
}
button {
width: 150px;
margin-bottom: 10px;
}
.vector.left{
clear: both;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="vector bottom">
<span>Some content</span>
<svg viewBox="0 0 40 100" preserveAspectRatio="none">
<polygon points="0,0 40,0 40,100 0,60" />
</svg>
</div>
<div class="vector top">
<span>Some content</span>
<svg viewBox="0 0 40 100" preserveAspectRatio="none">
<polygon points="0,40 40,0 40,100 0,100" />
</svg>
</div>
<div class="vector left">
<span>Some content</span>
<svg viewBox="0 0 40 100" preserveAspectRatio="none">
<polygon points="0,0 40,0 40,100 20,100" />
</svg>
</div>
<div class="vector right">
<span>Some content</span>
<svg viewBox="0 0 40 100" preserveAspectRatio="none">
<polygon points="0,0 20,0 40,100 0,100" />
</svg>
</div>
<div class='btn-container'>
<button id="increasew-vector">Increase Width</button>
<button id="increaseh-vector">Increase Height</button>
<button id="increaseb-vector">Increase Both</button>
</div>
Pros
- SVG is designed to produce scalable graphics and can work well with all dimension changes.
- Borders and hover effect can be achieved with minimal coding overhead.
- Image or gradient background can also be provided to the shape.
Cons
- Browser support is probably the only downside because IE8- doesn't support SVG but that can be mitigated by using libraries like Raphael and also VML. Moreover, the browser support is in no way worse than the other options.
Method 2 - Gradient Background
Linear gradients can still be used to produce the shape but not with angles as mentioned in the question. We have to use the to [side] [side]
syntax (thanks to vals) instead of specifying angles. When sides are specified, the gradient angles are automatically adjusted based on the container's dimensions.
$(document).ready(function() {
$('#increasew-gradient').on('click', function() {
$('.gradient').css({
'height': '100px',
'width': '150px'
});
});
$('#increaseh-gradient').on('click', function() {
$('.gradient').css({
'height': '150px',
'width': '100px'
});
});
$('#increaseb-gradient').on('click', function() {
$('.gradient').css({
'height': '150px',
'width': '150px'
});
});
})
div {
float: left;
height: 100px;
width: 100px;
margin: 10px 20px;
color: beige;
transition: all 1s;
}
.gradient{
position: relative;
}
.gradient.bottom {
background: linear-gradient(to top right, transparent 50%, tomato 50%) no-repeat, linear-gradient(to top right, transparent 0.1%, tomato 0.1%) no-repeat;
background-size: 100% 40%, 100% 60%;
background-position: 0% 100%, 0% 0%;
}
.gradient.top {
background: linear-gradient(to bottom right, transparent 50%, tomato 50%) no-repeat, linear-gradient(to bottom right, transparent 0.1%, tomato 0.1%) no-repeat;
background-size: 100% 40%, 100% 60%;
background-position: 0% 0%, 0% 100%;
}
.gradient.left {
background: linear-gradient(to top right, transparent 50%, tomato 50%) no-repeat, linear-gradient(to top right, transparent 0.1%, tomato 0.1%) no-repeat;
background-size: 40% 100%, 60% 100%;
background-position: 0% 0%, 100% 0%;
}
.gradient.right {
background: linear-gradient(to top left, transparent 50%, tomato 50%) no-repeat, linear-gradient(to top left, transparent 0.1%, tomato 0.1%) no-repeat;
background-size: 40% 100%, 60% 100%;
background-position: 100% 0%, 0% 0%;
}
.gradient span{
position: absolute;
}
.gradient.top span{
top: calc(40% + 5px); /* background size + buffer */
left: 5px;
height: 50%;
}
.gradient.bottom span{
top: 5px;
left: 5px;
height: 50%;
}
.gradient.left span{
left: 40%; /* background size */
top: 5px;
width: 50%;
}
.gradient.right span{
left: 5px;
top: 5px;
width: 50%;
}
/* Just for demo */
body {
background: radial-gradient(circle at 50% 50%, aliceblue, steelblue);
}
.btn-container {
position: absolute;
top: 0px;
right: 0px;
width: 150px;
}
button {
width: 150px;
margin-bottom: 10px;
}
.gradient.left{
clear:both;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="gradient bottom"><span>Some content</span>
</div>
<div class="gradient top"><span>Some content</span>
</div>
<div class="gradient left"><span>Some content</span>
</div>
<div class="gradient right"><span>Some content</span>
</div>
<div class='btn-container'>
<button id="increasew-gradient">Increase Width</button>
<button id="increaseh-gradient">Increase Height</button>
<button id="increaseb-gradient">Increase Both</button>
</div>
Pros
- Shape can be achieved and maintained even if the dimensions of the container are dynamic.
- Hover effect can be added by changing the gradient color.
Cons
- Hover effect will be triggered even when cursor is outside the shape but within the container.
- Adding borders would require tricky gradient manipulations.
- Gradients are known for producing jagged corners when the width (or height) is very big.
- Image backgrounds cannot be used on the shape.
Method 3 - Skew Transforms
In this method, a pseudo-element is added, skewed and positioned in such a way that it looks like one of the edges is slanted/angled.If the top or bottom edge is slanted, the skew should be along Y axis, else the rotation should be along X axis. The transform-origin
should have the side opposite to the slanted side.
$(document).ready(function() {
$('#increasew-skew').on('click', function() {
$('.skew').css({
'height': '100px',
'width': '150px'
});
});
$('#increaseh-skew').on('click', function() {
$('.skew').css({
'height': '150px',
'width': '100px'
});
});
$('#increaseb-skew').on('click', function() {
$('.skew').css({
'height': '150px',
'width': '150px'
});
});
})
div {
float: left;
height: 100px;
width: 100px;
margin: 50px;
color: beige;
transition: all 1s;
}
.skew {
padding: 10px;
position: relative;
background: tomato;
}
.skew:after {
position: absolute;
content: '';
background: inherit;
z-index: -1;
}
.skew.bottom:after,
.skew.top:after {
width: 100%;
height: 60%;
}
.skew.left:after,
.skew.right:after {
height: 100%;
width: 60%;
}
.skew.bottom:after {
bottom: 0px;
left: 0px;
transform-origin: top left;
transform: skewY(22deg);
}
.skew.top:after {
top: 0px;
left: 0px;
transform-origin: top left;
transform: skewY(-22deg);
}
.skew.left:after {
top: 0px;
left: 0px;
transform-origin: bottom left;
transform: skewX(22deg);
}
.skew.right:after {
top: 0px;
right: 0px;
transform-origin: bottom right;
transform: skewX(-22deg);
}
.skew:hover {
background: steelblue;
}
/* Just for demo */
body {
background: radial-gradient(circle at 50% 50%, aliceblue, steelblue);
}
.skew.bottom {
margin-top: 10px;
}
.skew.left {
clear: both;
}
.btn-container {
position: absolute;
top: 0px;
right: 0px;
width: 150px;
}
button {
width: 150px;
margin-bottom: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="skew bottom">Some content</div>
<div class="skew top">Some content</div>
<div class="skew left">Some content</div>
<div class="skew right">Some content</div>
<div class='btn-container'>
<button id="increasew-skew">Increase Width</button>
<button id="increaseh-skew">Increase Height</button>
<button id="increaseb-skew">Increase Both</button>
</div>
Pros
- Shape can be achieved even with borders.
- Hover effect will be restricted to within the shape.
Cons
- Dimensions need to increase proportionally for the shape to be maintained because when an element is skewed, its offset in Y-axis increases as
width
increases and vice-versa (try increasing thewidth
to200px
in the snippet). You can find more information about this here.
Method 4 - Perspective Transforms
In this method, the main container is rotated along the X or Y axis with a bit of perspective. Setting the appropriate value to transform-origin
would produce a slanted edge on only one side.
If the top or bottom side is slanted, the rotation should be along Y axis, else the rotation should be along X axis. The transform-origin
should have the side opposite to the slanted side.
$(document).ready(function() {
$('#increasew-rotate').on('click', function() {
$('.rotate').css({
'height': '100px',
'width': '150px'
});
});
$('#increaseh-rotate').on('click', function() {
$('.rotate').css({
'height': '150px',
'width': '100px'
});
});
$('#increaseb-rotate').on('click', function() {
$('.rotate').css({
'height': '150px',
'width': '150px'
});
});
})
div {
float: left;
height: 100px;
width: 100px;
margin: 50px;
color: beige;
transition: all 1s;
}
.rotate {
position: relative;
width: 100px;
background: tomato;
}
.rotate.bottom {
transform-origin: top;
transform: perspective(10px) rotateY(-2deg);
}
.rotate.top {
transform-origin: bottom;
transform: perspective(10px) rotateY(-2deg);
}
.rotate.left {
transform-origin: right;
transform: perspective(10px) rotateX(-2deg);
}
.rotate.right {
transform-origin: left;
transform: perspective(10px) rotateX(-2deg);
}
.rotate span {
position: absolute;
display: block;
top: 0px;
right: 0px;
width: 50%;
height: 100%;
}
.rotate.bottom span {
padding: 10px;
transform-origin: top;
transform: perspective(10px) rotateY(2deg);
}
.rotate.top span {
padding: 20px;
transform-origin: bottom;
transform: perspective(20px) rotateY(2deg);
}
.rotate.left span {
padding: 10px;
transform-origin: right;
transform: perspective(10px) rotateX(2deg);
}
.rotate.right span {
padding: 0px 30px;
transform-origin: left;
transform: perspective(10px) rotateX(2deg);
}
.rotate:hover {
background: steelblue;
}
/* Just for demo */
body {
background: radial-gradient(circle at 50% 50%, aliceblue, steelblue);
}
.rotate.left{
clear:both;
}
.btn-container {
position: absolute;
top: 0px;
right: 0px;
width: 150px;
}
button {
width: 150px;
margin-bottom: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="rotate bottom"><span>Some content</span>
</div>
<div class="rotate top"><span>Some content</span>
</div>
<div class="rotate left"><span>Some content</span>
</div>
<div class="rotate right"><span>Some content</span>
</div>
<div class='btn-container'>
<button id="increasew-rotate">Increase Width</button>
<button id="increaseh-rotate">Increase Height</button>
<button id="increaseb-rotate">Increase Both</button>
</div>
Pros
- Shape can be achieved with borders.
- Dimensions need not increase proportionally for the shape to be maintained.
Cons
- Content will also be rotated and hence they have to be counter rotated to look normal.
- Positioning text will be tedious if the dimensions are not static.
Method 5 - CSS Clip Path
In this method, the main container is clipped into the required shape using a polygon. The polygon's points should be modified depending on the side where the slanted edge is required.
$(document).ready(function() {
$('#increasew-clip').on('click', function() {
$('.clip-path').css({
'height': '100px',
'width': '150px'
});
});
$('#increaseh-clip').on('click', function() {
$('.clip-path').css({
'height': '150px',
'width': '100px'
});
});
$('#increaseb-clip').on('click', function() {
$('.clip-path').css({
'height': '150px',
'width': '150px'
});
});
})
.clip-path {
position: relative;
float: left;
margin: 20px;
height: 100px;
width: 100px;
background: tomato;
padding: 4px;
transition: all 1s;
}
.clip-path.bottom {
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 60%);
}
.clip-path.top {
-webkit-clip-path: polygon(0% 40%, 100% 0%, 100% 100%, 0% 100%);
}
.clip-path.left {
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 40% 100%);
}
.clip-path.right {
-webkit-clip-path: polygon(0% 0%, 60% 0%, 100% 100%, 0% 100%);
}
.clip-path .content {
position: absolute;
content: '';
height: calc(100% - 10px);
width: calc(100% - 8px);
background: bisque;
}
.clip-path.bottom .content {
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 60%);
}
.clip-path.top .content {
-webkit-clip-path: polygon(0% 40%, 100% 0%, 100% 100%, 0% 100%);
}
.clip-path .content.img {
top: 6px;
background: url(http://lorempixel.com/250/250);
background-size: 100% 100%;
}
/* Just for demo */
body {
background: radial-gradient(circle at 50% 50%, aliceblue, steelblue);
}
.clip-path.left {
clear: both;
}
.clip-path:hover {
background: gold;
}
.btn-container {
position: absolute;
top: 0px;
right: 0px;
margin: 20px;
width: 150px;
}
button {
width: 150px;
margin-bottom: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="clip-path bottom">
<div class="content">abcd</div>
</div>
<div class="clip-path top">
<div class="content img"></div>
</div>
<div class="clip-path left"></div>
<div class="clip-path right"></div>
<div class='btn-container'>
<button id="increasew-clip">Increase Width</button>
<button id="increaseh-clip">Increase Height</button>
<button id="increaseb-clip">Increase Both</button>
</div>
Pros
- Shape can be maintained even when the container is being resized dynamically.
- Hover effect will be perfectly restricted within the borders of the shape.
- Image can also be used as background for the shape.
Cons
- Browser support is very poor at present.
- Borders can be added by placing an absolutely positioned element on top of the shape and giving it the necessary clip but beyond a point it doesn't fit well when re-sizing dynamically.
Method 6 - Canvas
Canvas can also be used to produce the shape by drawing paths. The below snippet has a demo. Any text content required can be positioned on top of the shape.
window.onload = function() {
var canvasEls = document.getElementsByTagName('canvas');
for (var i = 0; i < canvasEls.length; i++) {
paint(canvasEls[i]);
}
function paint(canvas) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
if (canvas.className == 'bottom') {
ctx.moveTo(0, 0);
ctx.lineTo(250, 0);
ctx.lineTo(250, 100);
ctx.lineTo(0, 60);
} else if (canvas.className == 'top') {
ctx.moveTo(0, 40);
ctx.lineTo(250, 0);
ctx.lineTo(250, 100);
ctx.lineTo(0, 100);
} else if (canvas.className == 'left') {
ctx.moveTo(0, 0);
ctx.lineTo(250, 0);
ctx.lineTo(250, 100);
ctx.lineTo(60, 100);
} else if (canvas.className == 'right') {
ctx.moveTo(0, 0);
ctx.lineTo(190, 0);
ctx.lineTo(250, 100);
ctx.lineTo(0, 100);
}
ctx.closePath();
ctx.lineCap = 'round';
ctx.fillStyle = 'tomato';
ctx.fill();
}
$('#increasew-canvas').on('click', function() {
$('.container').css({
'width': '150px',
'height': '100px'
});
});
$('#increaseh-canvas').on('click', function() {
$('.container').css({
'width': '100px',
'height': '150px'
});
});
$('#increaseb-canvas').on('click', function() {
$('.container').css({
'width': '150px',
'height': '150px'
});
});
};
.container {
float: left;
position: relative;
height: 100px;
width: 100px;
margin: 20px;
color: beige;
transition: all 1s;
}
canvas {
height: 100%;
width: 100%;
}
.container > span {
position: absolute;
top: 5px;
left: 5px;
padding: 5px;
}
.top + span {
top: 40%; /* size of the angled area */
}
.left + span {
left: 40%; /* size of the angled area */
}
/* Just for demo */
body {
background: radial-gradient(circle at 50% 50%, aliceblue, steelblue);
}
.btn-container {
position: absolute;
top: 0px;
right: 0px;
width: 150px;
}
button {
width: 150px;
margin-bottom: 10px;
}
div:nth-of-type(3) {
clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="container">
<canvas height="100px" width="250px" class="bottom"></canvas> <span>Some content</span>
</div>
<div class="container">
<canvas height="100px" width="250px" class="top"></canvas> <span>Some content</span>
</div>
<div class="container">
<canvas height="100px" width="250px" class="left"></canvas> <span>Some content</span>
</div>
<div class="container">
<canvas height="100px" width="250px" class="right"></canvas> <span>Some content</span>
</div>
<div class='btn-container'>
<button id="increasew-canvas">Increase Width</button>
<button id="increaseh-canvas">Increase Height</button>
<button id="increaseb-canvas">Increase Both</button>
</div>
Pros
- Shape can be achieved and maintained even if the dimensions of the container are dynamic. Borders can also be added.
- Hover effect can be restricted to within the shape's boundaries by using
pointInpath
method. - Image or gradient background can also be provided to the shape.
- Better choice if real-time animation effects are needed as it doesn't require DOM manipulation.
Cons
- Canvas is raster based and hence the angled edges will become pixelated or blurred when scaled beyond a point *.
* - Avoiding pixelation would need repaints of the shape whenever viewport is resized. There is an example of it here but that is an overhead.
这篇关于形状有斜边(响应)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!