I'm interested if it's possible to create wrapped (or maybe better said twisted) border using CSS. Effect I wanted to achieve is in the picture.
问题:
回答1:
Most easiest and neat solution would be to use svg to create the border.
#container { position: relative; width: 200px; height: 30px; } #content { text-transform: uppercase; position: absolute; width: 200px; height: 30px; top: 0; text-align: center; line-height: 30px; } lorem ipsum You could even spice it up with some curves using quadratic curves.
#container { position: relative; width: 200px; height: 30px; margin-bottom: 30px; } #content { text-transform: uppercase; position: absolute; width: 200px; height: 30px; top: 0; text-align: center; line-height: 30px; } lorem ipsum lorem ipsum lorem ipsum You could easily add a drop shadow effect.
#container { position: relative; width: 200px; height: 30px; margin-bottom: 30px; } #content { text-transform: uppercase; position: absolute; width: 200px; height: 30px; top: 0; text-align: center; line-height: 30px; } lorem ipsum lorem ipsum lorem ipsum Alternatively you could always use :after and :before :pseudo-elements.
The width and height of the :after and :before :pseudo-elements were calculated using some basic trigonometry.
The opposite side is the width and height of the :after and :before :pseudo-elements. The one on the left is given top and right borders and the one on the right is given top and left borders. Then, the one on the left has been rotated 45deg and the one on the right has been rotated -45deg.
div { position: relative; text-transform: uppercase; width: 200px; height: 30px; text-align: center; line-height: 27px; border-top: 3px solid black; border-bottom: 3px solid black; box-sizing: border-box; } div:after, div:before { position: absolute; content: ''; width: 21.21px; height: 21.21px; border-top: 3px solid black; border-right: 3px solid black; transform: rotate(45deg); box-sizing: border-box; top: 1px; left: -9px; } div:after { border-right: 0; border-left: 3px solid black; left: 100%; margin-left: -10px; transform: rotate(-45deg); } lorem ipsum 回答2:
Yes, you can do this purely in CSS by manipulating the :before and :after psuedo elements.
The key advantages are that you can keep your HTML 'as is', and it maintains a strict seperation of concerns between content (html) and styling (CSS).
body { text-align: center; } div { border: 2px solid; display: inline-block; position: relative; padding: 0 40px; margin: 20px; height: 30px; line-height: 30px; overflow: hidden; border-right: 0; border-left: 0; } div:after, div:before { border: 2px solid; height: 30px; width: 30px; content: ''; display: block; position: absolute; top: -2px; transform: rotate(45deg); } div:after { right: -23px; } div:before { left: -23px; } Lorem Ipsum 回答3:
This is a different approach using pure CSS alone to achieve this effect (using the method explained in this answer but reverse rotation of elements).
Basically it involves two pseudo elements that are rotated with a bit of perspective and positioned one below the other to achieve the shape.
This approach works like below:
- Two pseudo-elements
:beforeand:afterwhich are roughly about half the size (including borders) of the main.buttonelement. The height of each pseudo-element is 35.5px + 3px border on one side (top/bottom) and 1.5px on the other side (because the two overlap at half distance). - The top half of the shape is achieved using the
:beforeelement whereas the bottom half is achieved using the:afterelement. - Using a
rotateXwith perspective to achieve the tilted effect and positioning to place the two elements such that they form the expected shape.
Note: There is a bit of extra styling for a sample
hovereffect which causes the shape to turn into an elongated hexagon. This is not part of the question but is added just for sample (and a bit of fun :)). Also, older versions of Chrome and Safari seems to be giving incorrect output for thehoverbehavior whereas the latest versions of all browsers are doing fine.
/* General Button Style */ .button { position: relative; width: 300px; height: 80px; line-height: 80px; text-align: center; text-transform: uppercase; color: #000; margin: 40px auto; box-sizing: border-box; } .button:before, .button:after { width: 300px; left: 0px; height: 35.5px; z-index: -1; border: 4px solid #000; border-top-width: 3px; border-bottom-width: 3px; } .button:before { border-bottom: none; } .button:after { border-top: none; } .button:before { position: absolute; content: ''; -webkit-transform: perspective(15px) rotateX(-3deg); -moz-transform: perspective(15px) rotateX(-3deg); transform: perspective(15px) rotateX(-3deg); } .button:after { position: absolute; top: 35.5px; content: ''; -webkit-transform: perspective(15px) rotateX(3deg); -moz-transform: perspective(15px) rotateX(3deg); transform: perspective(15px) rotateX(3deg); } /* Hover Styles */ .button:hover:before, .button:hover:after { background: #000; } .button:hover:before { top: -3px; -webkit-transform: perspective(15px) rotateX(3deg); -moz-transform: perspective(15px) rotateX(3deg); transform: perspective(15px) rotateX(3deg); } .button:hover:after { top: 38px; -webkit-transform: perspective(15px) rotateX(-3deg); -moz-transform: perspective(15px) rotateX(-3deg); transform: perspective(15px) rotateX(-3deg); } .button:hover { color: #fff; } As-is, this would degrade quite well in IE 8 and IE 9 into a square button with borders. However, due to the nullification of one border (border-bottom for :before and border-top for :after) it would leave a white area (resembling a strike-through line) in the middle. This can be overcome by adding a couple of IE
Output Screenshots from IE 9 and IE 8: (both normal and during hover)