Creating specific border effect - css

How do I create the border effect of each of the tiles in the Fifteen puzzle below (the sharp edges on each corner of the tiles)?

You can also use :pseudo elements and border
codepen - http://codepen.io/victorfdes/pen/GJYGKV
*,
*:before,
*:after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.a {
width: 100px;
display: inline-block;
height: 100px;
position: relative;
overflow: hidden;
}
.a:nth-child(even) .b {
background: #DCD8BB;
}
.b {
position: absolute;
width: 116px;
height: 116px;
border: 4px solid #8B8B83;
transform: rotate(45deg) translate(-50%, -50%);
transform-origin: left top;
top: 50%;
left: 50%;
background: #490506;
z-index: -1;
}
.b:before,
.b:after {
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
background: inherit;
border-color: inherit;
}
.b:before {
border-width: 0 4px;
border-style: solid;
width: 100px;
height: 60px;
}
.b:after {
border-width: 4px 0;
border-style: solid;
height: 100px;
width: 60px;
}
.b span {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
z-index: 1;
color: grey;
font-size: 30px;
}
<div class="a">
<div class="b">
<span>1</span>
</div>
</div>
<div class="a">
<div class="b">
<span>2</span>
</div>
</div>
<div class="a">
<div class="b">
<span>3</span>
</div>
</div>
<div class="a">
<div class="b">
<span>4</span>
</div>
</div>

SVG clip-path is what you are looking for, but it is not widely supported.
It is talked about here: Slanted Corner on CSS box
The one you want is called a Bevel Box:
-webkit-clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);
clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);

Related

CSS Responsive Hexagon Image Frame [duplicate]

This question already has answers here:
How to center an element horizontally and vertically
(27 answers)
Closed 6 months ago.
I'm trying to make a responsive hexagon image frame, but I'm stuck on aligning the inner hexagon. Does anyone know how to center the inner hexagon? Here's my code:
.inner {
background-color: red;
width: 95%;
height: 0%;
padding-bottom: 98%;
margin-top: auto;
margin-bottom: auto;
}
.outer {
background-color: mediumspringgreen;
width: 12%;
height: 0%;
padding-bottom: 13%;
}
.hexagon {
display: flex;
justify-content: center;
align-items: center;
position: relative;
-webkit-clip-path: polygon( 50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}
<div class="hexagon outer">
<div class="hexagon inner">
<img src="https://placekitten.com/400/400" class="absolute inset-0 h-full w-full" alt="" />
</div>
</div>
My result:
Expected result:
It seems as you use the padding only for your inner div, the outer div only gets that height. I would have a container that you put the width on, then you can add padding to your outer hexagon and absolutely position your inner hexagon:
.container {
width: 12%;
}
.inner {
background-color: red;
width: calc(100% - 10px);
/* can change this to be a percentage if you want a variable width border. with calc, the border will always be half of what you subtract */
height: calc(100% - 10px);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.outer {
background-color: blue;
width: 100%;
padding-top: 100%;
position: relative;
}
.hexagon {
clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);
}
.img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="hexagon outer">
<div class="hexagon inner">
<img src="https://placekitten.com/400/400" class="img">
</div>
</div>
</div>
From comments solution using aspect ratio instead of padding and inset instead of calc on the width of inner:
.container {
width: 12%;
}
.inner {
background-color: red;
/* insets the element 5px from the edges of
the element against which its positioned: */
inset: 5px;
position: absolute;
}
.outer {
/* allows one dimension to be set (here 'inline-size'/'width'),
and the other dimension ('block-size'/'height') will be
an equal width: */
aspect-ratio: 1;
background-color: blue;
/* logical property, equivalent to 'width' in the English -
left-to-right - language: */
inline-size: 100%;
position: relative;
}
.hexagon {
clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);
}
.img {
width: 100%;
object-fit: cover;
}
<div class="container">
<div class="hexagon outer">
<div class="hexagon inner">
<img src="https://placekitten.com/400/400" class="img">
</div>
</div>
</div>
Try it:
.inner {
background-color: red;
width: 95%;
height: 0%;
padding-bottom: 98%;
margin-top: auto;
margin-bottom: auto;
}
.outer {
background-color: mediumspringgreen;
width: 12%;
height: 0%;
padding-bottom: 13%;
}
.hexagon {
display: flex;
justify-content: center;
align-items: center;
-webkit-clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
position: absolute;
top: 50%;
left: 50%;
-moz-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
<div class="hexagon outer">
<div class="hexagon inner">
<img src="https://placekitten.com/400/400" class="absolute inset-0 h-full w-full" alt="" />
</div>
</div>

css 2 column design with split face image

I'm trying to accomplish the following in CSS:
So you start with 2 halves, each of them showing half a picture of someones face (these images have their face in the exact center). By some mean of interaction the sides pan out. This is what I tried first:
.container {
display: flex;
align-items: stretch;
width: 414px;
height: 736px;
}
.container__section {
display: flex;
flex-direction: column;
justify-content: center;
width: 50%;
padding: 1rem;
}
.container__section:before {
content: "";
position: absolute;
top: 0;
bottom: 0;
overflow: hidden;
}
.container__section--left {
background-color: #83b1be;
}
.container__section--left:before {
background: url('http://i68.tinypic.com/2mwzddh.jpg') no-repeat;
background-position: left 50% center;
transform: translateX(0%);
left: 0;
right: 50%;
}
.container__section--right {
background-color: #80bb94;
}
.container__section--right:before {
background: url('http://i68.tinypic.com/2s7gcav.jpg') no-repeat;
background-position: right 50% center;
transform: translateX(0%);
right: 0;
left: 50%;
}
<div class="container">
<div class="container__section container__section--left">
<p class="homepage__section-detail">
lorem ipsum
</p>
</div>
<div class="container__section container__section--right">
<p class="container__section-detail">
lorem ipsum
</p>
</div>
</div>
It also seems that the images aren't loaded/blocked within the code snippet here above. If someone knows how to use images?
I'd probably layer the images in a single div (in this case using CSS-Grid) but you could use positioning...
Then use a clip-path to clip one in half. This property is animatable too.
.image-wrap {
width: 300px;
margin: 1em auto;
border: 1px solid grey;
display: grid;
overflow: hidden;
}
.image-wrap div {
grid-row: 1/2;
grid-column: 1/2;
}
img {
display: block;
max-width: auto;
height: 100%;
}
.one {
transition: -webkit-clip-path .5s ease;
transition: clip-path .5s ease;
transition: clip-path .5s ease, -webkit-clip-path .5s ease;
-webkit-clip-path: polygon(0% 0%, 50% 0%, 50% 100%, 0% 100%);
clip-path: polygon(0% 0%, 50% 0%, 50% 100%, 0% 100%);
}
.image-wrap:hover .one {
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
}
<div class="image-wrap">
<div class="one"><img src="https://www.placecage.com/300/200" alt=""></div>
<div class="two">
<img src="http://www.fillmurray.com/300/200" alt="">
</div>
</div>

How to set the color of pie slice without using clip-path?

I've created a simple pie-chart (2 slices) and set the background color of the small slice by creating a layer with the help of CSS clip-path.
My problem is - clip path isn't working in Microsoft Edge.
Is there any better way to do it?
Codepen: https://codepen.io/anon/pen/QMPPOQ?editors=1100
body {
background: #e74c3c;
margin-top: 45px;
}
.chart {
width: 400px;
max-width: 90vw;
height: 400px;
margin: 0 auto;
border-radius: 50%;
border: 3px solid white;
position: relative;
background: rgba(255, 255, 255, .3);
overflow: hidden;
}
.chart-inner {
position: relative;
width: 100%;
height: 100%;
transform: translateY(-1.5px);
}
.chart .line {
width: 50%;
height: 3px;
background: white;
position: absolute;
top: 50%;
transform-origin: 100%;
transform: rotate(90deg);
}
.chart .line-spl {
transform: rotate(60deg); /* 1/12 */
}
.layer {
z-index: -10;
position: relative;
background: rgba(255, 255, 255, .6);
-webkit-clip-path: polygon(49% 55%, 25% 13%, 49% 8%);
-ms-clip-path: polygon(40% 50%, 18% 12%, 40% 5%);
-moz-clip-path: polygon(40% 50%, 18% 12%, 40% 5%);
clip-path: polygon(49% 55%, 25% 13%, 49% 8%);
height: 450px;
width: 465px;
left: -29px;
top: -52px;
}
<div class="chart">
<div class="chart-inner">
<div class="line"></div>
<div class="line line-spl"></div>
<div class="layer"></div>
</div>
</div>

Make a lines orbiting around circle div

i am trying to create animation that a few lines are rotating around circle div.
Something like this
http://prntscr.com/dxoe8o
this is my html & css
.outCircle {
width: 20px;
height: 20px;
background-color: lightblue;
left: 270px;
position: absolute;
top: 50px;
-moz-border-radius: 100px;
-webkit-border-radius: 100px;
border-radius: 100px;
}
.duringTen {
-webkit-animation-duration: 5s;
}
.infinite {
-webkit-animation-iteration-count: infinite;
}
.linear {
-webkit-animation-timing-function: linear;
}
.counter {
width: 30px;
height: 30px;
-webkit-animation-duration: inherit;
-webkit-animation-direction: reverse;
-webkit-animation-timing-function: inherit;
-webkit-animation-iteration-count: inherit;
-webkit-animation-name: inherit;
}
.rotate {
width: 100%;
height: 100%;
-webkit-animation-name: circle;
position: relative;
z-index: 10;
display: block;
}
.inner {
width: 20px;
height: 2px;
-moz-border-radius: 50px;
-webkit-border-radius: 50px;
border-radius: 100px;
position: absolute;
left: 0px;
top: 5px;
background-color: red;
display: block;
}
.red {
background: red;
}
.green {
background: green;
}
#keyframes circle {
from {
-webkit-transform: rotateZ(0deg)
}
to {
-webkit-transform: rotateZ(360deg)
}
}
<div class="outCircle">
<div class="rotate linear infinite duringTen">
<div class="counter">
<div class="inner">
</div>
</div>
</div>
</div>
My try is only with one line but i would like to create a few more lines like on the picture i posted above.
This is as far as i have come
Perhaps something like this:
.outCircle {
width: 20px;
height: 20px;
background-color: lightblue;
position: relative;
border-radius: 50%;
margin: 100px auto;
}
.marker {
width: 50px;
height: 2px;
position: absolute;
top: 50%;
left: 50%;
background: linear-gradient(to right, black, black 25%, transparent 25%, transparent 75%, black 75%);
transform: translate(-50%, -50%);
}
.vert {
width: 2px;
height: 50px;
background: linear-gradient(to bottom, black, black 25%, transparent 25%, transparent 75%, red 75%);
transform: translate(-50%, -50%);
}
.angle-1 {
transform: translate(-50%, -50%) rotate(45deg);
}
.angle-2 {
transform: translate(-50%, -50%) rotate(-45deg);
}
.inner {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
animation: circle 3s linear infinite;
}
#keyframes circle {
from {
transform: rotateZ(0deg);
}
to {
transform: rotateZ(360deg);
}
}
<div class="outCircle">
<div class="inner">
<div class="marker horiz"></div>
<div class="marker vert"></div>
<div class="marker angle-1"></div>
<div class="marker angle-2"></div>
</div>
</div>
Note, this is quick and dirty...with a little time it could be simplified, perhaps by using pseudo-elements for some of the markers.
In general though, a SVG might be better.

Left/right transparent cut out arrow

I am aware this has been answered previously however that was for the bottom of a div and I cannot work out how to do it for the left and right of a div.
I am trying to acheive the same effect as this:
BODY {
background: url(http://farm6.staticflickr.com/5506/9699081016_ba090f1238_h.jpg) 0 -100px;
}
#wrapper {
overflow: hidden;
height: 116px;
}
#test {
height: 100px;
background-color: #ccc;
position: relative;
}
#test:before {
content: "";
position: absolute;
left: -6px;
width: 50%;
height: 16px;
top: 100px;
background-color: #ccc;
-webkit-transform: skew(-40deg);
-moz-transform: skew(-40deg);
-o-transform: skew(-40deg);
-ms-transform: skew(-40deg);
transform: skew(-40deg);
}
#test:after {
content: "";
position: absolute;
right: -6px;
width: 50%;
height: 16px;
top: 100px;
background-color: #ccc;
-webkit-transform: skew(40deg);
-moz-transform: skew(40deg);
-o-transform: skew(40deg);
-ms-transform: skew(40deg);
transform: skew(40deg);
}
<div id="wrapper">
<div id="test"></div>
</div>
But with the cut out on the left and another with the cut out on the right.
This solution is adapted from this answer : Transparent arrow/triangle
The point is to use two skewed pseudo elements to make the transparent cut out arrow. Both pseudo elements are absolutely positioned and skewed.
In the following demo, the arrow is on the left. To make the same on on the right, you could duplicate the .arrow element and use scaleX(-1) + positioning on the second one. This will allow you to change both sides at the same time and have less CSS. Or you can make a new element based on the first one and change the positioning and skew properties.
DEMO
.wrap {
position: relative;
overflow: hidden;
width: 70%;
margin: 0 auto;
}
.wrap img {
width: 100%;
height: auto;
display: block;
}
.arrow {
position: absolute;
left: 0; top:0;
width: 3%;
height:100%;
background-color: rgba(255,255,255,.8);
}
.arrow:before, .arrow:after {
content:'';
position: absolute;
left: 100%;
width: 100%;
height:50%;
background-color: inherit;
}
.arrow:before {
bottom: 50%;
-ms-transform-origin: 0 100%;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-ms-transform: skewY(-45deg);
-webkit-transform: skewY(-45deg);
transform: skewY(-45deg);
}
.arrow:after {
top: 50%;
-ms-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-ms-transform: skewY(45deg);
-webkit-transform: skewY(45deg);
transform: skewY(45deg);
}
<div class="wrap">
<img src="https://farm7.staticflickr.com/6217/6216951796_e50778255c.jpg" />
<div class="arrow"></div>
</div>
For the same output, you can use an svg :
DEMO
.wrap {
position: relative;
overflow: hidden;
width: 70%;
margin: 0 auto;
}
.wrap img {
width: 100%;
height: auto;
display: block;
}
.arrow{
position:absolute;
left:0; top:0;
height:100%;
}
<div class="wrap">
<img src="https://farm7.staticflickr.com/6217/6216951796_e50778255c.jpg" />
<svg class="arrow" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 10 100">
<path d="M-1 -1 H10 V45 L5 50 L10 55 V101 H-1z" fill="#fff" fill-opacity="0.8" stroke-width="0"/>
</svg>
</div>
It can be made with a single element using inset box-shadow and pseudo-elements :before and :after
The elements are skewed by 45deg and -45deg to create the transparent gap. Inset box-shadow is used to increase the width of the arrow banner.
Fiddle (1 element)
body {
font-size: 10px;
}
div {
background: url('https://farm7.staticflickr.com/6217/6216951796_e50778255c.jpg');
height: 33.3em;
width: 50em;
position: relative;
overflow: hidden;
box-shadow: inset 2em 0 0 0 rgba(255, 255, 255, 0.6);
}
div:before, div:after {
content: "";
position: absolute;
left: 2em;
background-color: rgba(255, 255, 255, 0.6);
height: 25em;
width: 2em;
-webkit-transform-origin: 0% 0%;
-moz-transform-origin: 0% 0%;
-ms-transform-origin: 0% 0%;
transform-origin: 0% 0%;
}
div:before {
bottom: -8.35em;
-webkit-transform: skewY(45deg);
-moz-transform: skewY(45deg);
-ms-transform: skewY(45deg);
transform: skewY(45deg);
}
div:after {
top: -8.35em;
-webkit-transform: skewY(-45deg);
-moz-transform: skewY(-45deg);
-ms-transform: skewY(-45deg);
transform: skewY(-45deg);
}
<div></div>
Bugs : Browser rendering of box-shadow isn't consistent when using veiwport units. On zooming-out to 33%, GC shows 1px gap b/w pseudo-element and box-shadow. This bug doesn't occur with px and em units on zooming.
A better approach than the one given above would be to use one element on top of img element. The rest properties (overflow: hidden;, box-shadow) too are used, but this doesn't have the gap between the arrow even on zooming.
Fiddle (2 elements)
Note :
Ideas used from earlier post here.
All measurements are done in em with a set font-size of 10px.
You could use CSS3's clip-path property but it's a bit bleeding-edge. However, if you don't need to support IE there are plenty of useful examples at http://css-tricks.com/clipping-masking-css/
div {background: yellow; width:400px; height:300px;}
div img {
-webkit-clip-path: polygon(10% 0%, 90% 0%, 90% 100%, 90% 40%, 100% 50%, 90% 60%, 90% 100%, 10% 100%, 10% 60%, 0% 50%, 10% 40%);
clip-path: polygon(10% 0%, 90% 0%, 90% 100%, 90% 40%, 100% 50%, 90% 60%, 90% 100%, 10% 100%, 10% 60%, 0% 50%, 10% 40%);
}
<div><img src="http://lorempixel.com/400/300/nature/" /></div>
Hey I just modified your existing one. Probably could have done it a bit cleaner but you get the idea. This is the left side. Pretty easy to swap it to the right from this.
JSFiddle
HTML
<div id="wrapper">
<div id="test"><div id="fill"></div>
<div id="fill2"></div></div>
</div>
CSS
BODY{
background: url(http://farm6.staticflickr.com/5506/9699081016_ba090f1238_h.jpg) 0 -100px;}
#wrapper {
overflow: hidden;
height: 116px;}
#fill{
height: 40px;
position:absolute;
width:30px;
left:-30px;
background: #ccc;}
#fill2{
height: 40px;
position:absolute;
width:30px;
background: #ccc;
bottom:0;
left:-30px;}
#test {
height: 116px;
width: 692px;
background-color: #ccc;
position: relative;
float:right;}
#test:before {
content:"";
position: absolute;
top: 40px;
height: 50%;
width: 30px;
left: 0;
background-color: #ccc;
-webkit-transform: skew(40deg);
-moz-transform: skew(40deg);
-o-transform: skew(40deg);
-ms-transform: skew(40deg);
transform: skew(40deg);}
#test:after {
content:"";
position: absolute;
bottom: 40px;
height: 50%;
width: 30px;
left: 0;
background-color: #ccc;
-webkit-transform: skew(-40deg);
-moz-transform: skew(-40deg);
-o-transform: skew(-40deg);
-ms-transform: skew(-40deg);
transform: skew(-40deg);}

Resources