CSS Responsive Hexagon Image Frame [duplicate] - css

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>

Related

Css animation: fill a div with a color from left to right

I'm trying to create an animated background fill effect (still learning animation) but the fill color jumps quickly before it reaches the end of the div. What's the issue and how to fix it? Thanks in advance.
.outer {
margin: 50px;
}
.button {
border: 1px solid black;
border-radius: 3px;
width: 100px;
height: 30px;
display: block;
background: linear-gradient(to right, black 50%, transparent 50%);
background-size: 200% 100%;
background-position: right bottom;
animation: makeItfadeIn 3s 1s;
animation-fill-mode:forwards;
}
#-webkit-keyframes makeItfadeIn {
100% {
background-position: left bottom;
background: linear-gradient(to right, black 100%, black 0%);
}
}
#keyframes makeItfadeIn {
100% {
background-position: left bottom;
background: linear-gradient(to right, black 100%, black 0%);
}
}
<div class="outer">
<div class="button">
</div>
</div>
Background inside the animation is the culprit. You simply need to animate the position from right to left:
.outer {
margin: 50px;
}
.button {
border: 1px solid black;
border-radius: 3px;
width: 100px;
height: 30px;
display: block;
background: linear-gradient(to right, black 50%, transparent 0);
background-size: 200% 100%;
background-position: right;
animation: makeItfadeIn 3s 1s forwards;
}
#keyframes makeItfadeIn {
100% {
background-position: left;
}
}
<div class="outer">
<div class="button">
</div>
</div>
Related to get more details: Using percentage values with background-position on a linear-gradient

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>

flipping an image horizontally with CSS

I'm trying to build a frame. I did the top edge properly, but when doing the left edge it doesn't output properly. The left edge is almost correct, I just need to flip it horizontally from its current position.
Could you flip it for me and provide me a working example on your answer (snippet preview) or JSFiddle?
.trapezoid-top {
width: 400px;
height: 100px;
background-image: url('https://image.ibb.co/e5Kaw7/image.png');
background-size: contain;
clip-path: polygon(0 0, 100% 0, calc(100% - 100px) 100%, 100px 100%);
transform-origin: top left;
transform: rotate(0deg);
}
.trapezoid-left {
width: 600px;
height: 100px;
margin-top: -100px;
background-image: url('https://image.ibb.co/e5Kaw7/image.png');
background-size: contain;
clip-path: polygon(0 0, 100% 0, calc(100% - 100px) 100%, 100px 100%);
transform-origin: top left;
transform: rotate(90deg);
}
<div style="margin:0 100px;">
<div class="trapezoid-top"></div>
<div class="trapezoid-left"></div>
</div>
Thanks!
Try this:
CSS:
.container {
position: relative;
margin: 0 100px;
}
.trapezoid-top {
width: 400px;
height: 100px;
background-image: url('https://image.ibb.co/e5Kaw7/image.png');
background-size: contain;
clip-path: polygon(0 0, 100% 0, calc(100% - 100px) 100%, 100px 100%);
transform-origin: top left;
transform: rotate(0deg);
}
.trapezoid-left {
width: 600px;
height: 100px;
margin-top: -100px;
background-image: url(https://image.ibb.co/e5Kaw7/image.png);
background-size: contain;
clip-path: polygon(0 0, 100% 0, calc(100% - 100px) 100%, 100px 100%);
transform-origin: top right;
transform: rotate(-90deg);
position: absolute;
right: calc(100% - 16px);
}
HTML:
<div class="container">
<div class="trapezoid-top"></div>
<div class="trapezoid-left"></div>
</div>
Change transform-origin to top right and position the element to place it on left.
Demo: http://jsfiddle.net/GCu2D/3568/

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>

Creating specific border effect

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%);

Resources