How can you join CSS hexagon elements in a custom layout? - html

This is the layout I'm looking to achieve:
I've created the hexagon with this css:
.hexagon {
width: 100px;
height: 55px;
background: red;
position: relative;
display:inline-block;
margin:0.2em;
}
.hexagon:before {
content: "";
position: absolute;
top: -25px;
left: 0;
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 25px solid red;
}
.hexagon:after {
content: "";
position: absolute;
bottom: -25px;
left: 0;
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 25px solid red;
}
However, I'm looking to find out how to fill them with an image.
Here is a pen:https://codepen.io/1istbesser/pen/ddypXK
How do I put images inside the hexagon so that it covers all of it? If I use background-image on #hexagon1, the image only covers the middle part.

The problem you're going to run into is that using CSS triangles to create a hexagon actually yields square boxes with one or two borders filled in (and the rest transparent). This has two effects:
You can't easily put an image into the filled border so that it's clipped.
You can't make the hexagon - and only the hexagon - clickable: the whole set of rectangles will always be clickable, which will make your layout tricky where they overlap.
You're going to need something that can produce an actual hexagon. Inline SVG with a clip-path is a good fit - unlike clip-path in CSS, it's supported pretty much wherever SVG is. Here's an example:
<svg class="svg-graphic" width="300" height="300" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<clipPath id="hexagonal-mask">
<polygon points="300,150 225,280 75,280 0,150 75,20 225,20" />
</clipPath>
</defs>
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png" preserveAspectRatio="xMidYMin slice"/>
</svg>
Here's a more detailed example showing clickable hexagons, and re-use of the clip path definition:
.svg-template {
position: absolute;
}
.honeycomb {
list-style: none;
margin: 0;
padding: 0;
position: relative;
width: 1200px;
height: 1200px;
border: 1px solid #DDD;
}
.honeycomb li {
margin: 0;
padding: 0;
position: absolute;
}
.honeycomb li:nth-child(1) {
top: 0;
left: 0;
}
.honeycomb li:nth-child(2) {
top: 0;
left: 290px;
}
.honeycomb li:nth-child(3) {
top: 0;
left: 580px;
}
.honeycomb li:nth-child(4) {
top: 240px;
left: 145px;
}
.honeycomb li:nth-child(5) {
top: 240px;
left: 435px;
}
.honeycomb li:nth-child(6) {
top: 240px;
left: 725px;
}
.honeycomb li a {
cursor: pointer;
}
.honeycomb li a:hover image{
opacity: 0.5;
}
<svg class="svg-template" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<clipPath id="hexagonal-mask">
<polygon points="50 0, 95 25, 95 75, 50 100, 5 75, 5 25" />
</clipPath>
</defs>
</svg>
<ul class="honeycomb">
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
<li>
<svg width="300" height="300" viewBox="0 0 100 100" >
<a href="#something">
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://i.imgur.com/grp9BU1.png"/>
</a>
</svg>
</li>
</ul>

You need to consider another way if you want to use image as background. You are relying on pseudo element so your hexagone is not one element and thus you cannot use background image to cover the whole area.
Here is an idea using clip-path:
* {
background-color: black;
}
section {
margin-top: 3em;
display: flex;
flex-flow: column;
align-items: center;
}
.hexagon {
width: 100px;
height: 100px;
background: url(https://lorempixel.com/100/100/) 0 0/cover no-repeat;
position: relative;
display: inline-block;
margin: -10px 0.2em;
-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%);
}
<section>
<div class="row">
<div class="hexagon" id="hexagon1"></div>
<div class="hexagon" id="hexagon2"></div>
<div class="hexagon" id="hexagon3"></div>
<div class="hexagon" id="hexagon4"></div>
</div>
<div class="row">
<div class="hexagon" id="hexagon5"></div>
<div class="hexagon" id="hexagon6"></div>
<div class="hexagon" id="hexagon7"></div>
<div class="hexagon" id="hexagon8"></div>
<div class="hexagon" id="hexagon9"></div>
</div>
</section>

What you could do is draw an SVG and than put the image as mask in css
https://codepen.io/noahblon/post/coloring-svgs-in-css-background-images
*{
background-color:black;
}
section{
margin-top:3em;
display:flex;
flex-flow: column;
align-items: center;
}
.hexagon {
width: 100px;
height: 110px;
background: red;
position: relative;
display:inline-block;
margin:0.2em;
-webkit-mask:url(https://svgshare.com/i/5Fk.svg) no-repeat 50% 50%;
mask:url(https://svgshare.com/i/5Fk.svg) no-repeat 50% 50%;
background-image: url('https://img1.ibxk.com.br/2017/07/13/13160112901226.jpg?w=700');
background-size: cover;
background-position: center;
}
.row{
text-align: center;
margin-top: -25px
}
<section>
<div class="row">
<div class="hexagon" id="hexagon1"></div>
<div class="hexagon" id="hexagon2"></div>
<div class="hexagon" id="hexagon3"></div>
<div class="hexagon" id="hexagon4"></div>
<div class="row">
<div class="hexagon" id="hexagon5"></div>
<div class="hexagon" id="hexagon6"></div>
<div class="hexagon" id="hexagon7"></div>
</div>
<div class="row">
<div class="hexagon" id="hexagon8"></div>
<div class="hexagon" id="hexagon9"></div>
</div>
</section>

I made this code
Codepen
I changed the way you draw the element, instead adding the border top with the color red, I added the sides with a background, but you'd need to know the background-color of the page to do that, so I put the image above the box and the before and after above the image
CSS
*{
background-color:black;
}
section{
margin-top:3em;
display:flex;
flex-flow: column;
align-items: center;
}
.hexagon {
width: 100px;
height: 110px;
background: red;
position: relative;
display:inline-block;
margin:0.2em;
overflow: hidden;
}
.hexagon img{
position: absolute;
left: 50%;
top: 50%;
min-width: 100%;
min-height: 100%;
height: 100%;
transform: translate(-50%, -50%);
z-index: 1;
}
.hexagon:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border-right: 50px solid black;
border-left: 50px solid black;
border-bottom: 25px solid transparent;
z-index: 2;
}
.hexagon:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 0;
border-right: 50px solid black;
border-left: 50px solid black;
border-top: 25px solid transparent;
z-index: 2;
}
.row{
margin-top:1.3em;
}
.hexagon#hexagon2{
background-color: purple;
}
.hexagon#hexagon2:before{
border-bottom-color: purple;
}
.hexagon#hexagon2:after{
border-top-color: purple;
}
.hexagon#hexagon3{
background-color: white;
}
.hexagon#hexagon3:before{
border-bottom-color: white;
}
.hexagon#hexagon3:after{
border-top-color: white;
}
.hexagon#hexagon4{
background-color: orange;
}
.hexagon#hexagon4:before{
border-bottom-color: orange;
}
.hexagon#hexagon4:after{
border-top-color: orange;
}

Related

How to create a ban icon from html css?

I am trying to create a ban icon (created from html & css) over an image but I am having a hard time creating it. I have created somewhat static-looking ban icon but it seems perfect and not responsive. Can anyone please guide me on how this can be built?
What i have done so far:
.ban-icon-container{
position: absolute;
top: -10px;
left: 20%;
}
.ban-icon-circle{
width: 290px;
border: 8px solid red;
background: transparent;
height: 290px;
border-radius: 100%;
}
.ban-icon-bar{
height: 1px;
border: 7px solid red;
transform: translate(-1px, -151px) rotate(50deg);
width: 290px;
}
<div class="mt-2 flex align-center">
<div class="m-5 mt-16 mx-auto">
<div class="relative">
<img class="object-contain ban-icon-imgg" src="/img.jpg" alt="img" />
<div class="ban-icon-container">
<div class="ban-icon-circle">
</div>
<div class="ban-icon-bar">
</div>
</div>
</div>
</div>
</div>
Why have you used an attribute named className?
Change the attribute to class and also tweak the marked styles a bit.
Method 1
<style type="text/css">
.ban-icon-container{
position: absolute;
top: -10px;
left: 20%;
}
.ban-icon-circle{
width: 290px;
border: 8px solid red;
background: transparent;
height: 290px;
border-radius: 100%;
}
.ban-icon-bar{
//Change the height to 0px
height: 0px;
border: 7px solid red;
transform: translate(-1px, -151px) rotate(50deg);
//And the width to 240px
width: 240px;
}
</style>
<div class="mt-2 flex align-center">
<div class="m-5 mt-16 mx-auto">
<div class="relative">
<img class="object-contain ban-icon-imgg" src="jpg" alt="img" />
<div class="ban-icon-container">
<div class="ban-icon-circle">
</div>
<div class="ban-icon-bar">
</div>
</div>
</div>
</div>
</div>
Method 2 recommended
You can try using Font Awesome ban icon
I think the best way to create vector icon is SVG. Look at my code this way you can create any icon and this icon will behave like and image. You can scale it accordingly.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Ban Icon</title>
<style>
.ban-icon-container {
position: absolute;
top: 10px;
left: 20%;
}
.ban-icon-circle {
width: 290px;
border: 8px solid red;
background: transparent;
height: 290px;
border-radius: 100%;
}
.ban-icon-bar {
border: 7px solid red;
transform: translate(-1px, -151px) rotate(50deg);
}
</style>
</head>
<body>
<div class="mt-2 flex align-center">
<div class="m-5 mt-16 mx-auto">
<div class="relative">
<img class="object-contain ban-icon-imgg" src="/img.jpg" alt="img" />
<div class="ban-icon-container">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="101" height="101" viewBox="0 0 101 101" preserveAspectRatio="xMidYMid meet">
<circle cx="51" cy="51" r="48" stroke="black" stroke-width="3" fill="none" />
<line x1="17" y1="84" x2="84" y2="17" stroke="black" stroke-width="3" />
</svg>
</div>
</div>
</div>
</div>
</body>
</html>
This is the only code that is creating your ban icon. You can change colors and stroke width
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="101" height="101" viewBox="0 0 101 101" preserveAspectRatio="xMidYMid meet">
<circle cx="51" cy="51" r="48" stroke="black" stroke-width="3" fill="none" />
<line x1="17" y1="84" x2="84" y2="17" stroke="black" stroke-width="3" />
</svg>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper {
position: relative;
width: 220px;
height: 220px;
}
img {
width: 100%;
height: 100%;
border-radius: 6px;
}
.ban-icon::before,
.ban-icon::after {
position: absolute;
display: block;
content: '';
width: 70%;
height: 35%;
border-top-left-radius: 100px;
border-top-right-radius: 100px;
border: 10px solid red;
z-index: 1;
}
.ban-icon::before {
top: 15%;
right: -8px;
transform: rotate(45deg);
border-bottom: 10px solid red;
}
.ban-icon::after {
bottom: 15%;
left: -8px;
transform: rotate(-135deg);
border-bottom: 0;
}
<div class="wrapper">
<div class="ban-icon"></div>
<img src="https://www.w3schools.com/html/img_chania.jpg">
</div>

An SVG property that is respected only when inline, not through CSS

Supposedly, all SVG presentation attributes can be used as CSS properties.
And yet preserveAspectRatio appears to be observed only when it is an inline property, not through CSS.
html, body { width: 100%; height: 100%; margin: 0; }
.wrapper {
width: 50%; height: 10%;
}
.box {
padding: 10px; margin: 5px;
border: 5px solid #888; border-radius: 5px;
background-color: #eee; color: #000;
position: relative;
}
rect.rfoo { fill: #8af; }
svg.myrect1 {
position: absolute;
preserveAspectRatio: none;
left:0; top:0; width:100%; height:100%;
}
svg.myrect2 {
position: absolute;
left:0; top:0; width:100%; height:100%;
}
<div class="box wrapper">
<svg class="myrect1" viewBox="0 0 300 200">
<rect class="rfoo" x="25" y="25" width="250" height="150"></rect>
</svg>
</div>
<div class="box wrapper">
<svg preserveAspectRatio="none" class="myrect2" viewBox="0 0 300 200">
<rect class="rfoo" x="25" y="25" width="250" height="150"></rect>
</svg>
</div>
Why?
preserveAspectRatio is not a presentation attribute.

bottom 0 in IE for all screen size

I want my svg images to be on bottom of my block (position:absolute, bottom:0). But in Internet Explorer it doesn't work (displays in the center). I can set width and height to svg and it will work somehow, but it will broke on another device with smaller/bigger screen size. How can I resolve this problem? Thank you!
Here is the code codepen
.wrapper {
padding: 150px 20px 50px;
text-align: center;
color: #fff;
}
.main {
background-color: #000;
line-height: 48px;
position: relative;
}
svg {
position: absolute;
bottom: 0;
}
.left {
left: 0;
}
.right {
right: 0;
}
<div class="main">
<div class="wrapper">
<div class="text">Some text here</div>
<button>click</button>
</div>
<svg class="left" fill="#fff" viewBox="0 0 1300 150" width="50%">
<polygon points="0,0 0,150 1300,150"></polygon>
</svg>
<svg class="right" fill="#fff" viewBox="0 0 1300 150" width="50%">
<polygon points="1300,0 0,150 1300,150"></polygon>
</svg>
</div>
You can achieve the same with using either simple divs or with pseudo elements. The following is an example I created to demonstrate both approaches.
https://codepen.io/Nasir_T/pen/oEYYob
The example uses position along with border to set the bottom design the way your want. You can use the div solution if you want to place images in it or use the pseudo solution if only want to show arrow cut in the design at the bottom.
If you want a background image, why not use a background-image??
.wrapper {
padding: 150px 20px 50px;
text-align: center;
color: #fff;
}
.main {
background-color: #000;
line-height: 48px;
position: relative;
background-image: url('data:image/svg+xml,<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg viewBox="0 0 52 3" xmlns="http://www.w3.org/2000/svg"><polygon points="0,0 26,3 52,0 52,3 0,3" fill="#fff" /></svg>');
background-repeat: no-repeat;
background-position: center bottom;
}
<div class="main">
<div class="wrapper">
<div class="text">Some text here</div>
<button>click</button>
</div>
</div>
This can be accomplished using CSS alone.
We can make triangle shape in CSS. Stick a triangle at the bottom of your main container. Will give the same effect.
.wrapper {
padding: 110px 20px 50px;
text-align: center;
color: #fff;
}
.main {
background-color: #000;
line-height: 48px;
position: relative;
width: 1000px;
}
.arrow-down {
width: 0;
height: 0;
border-left: 500px solid transparent;
border-right: 500px solid transparent;
border-top: 50px solid #000;
position:absolute;
bottom:-50px;
}
svg {
position: absolute;
bottom: 0;
}
.left {
left:0;
}
.right {
right:0;
}
<div class="main">
<div class="wrapper">
<div class="text">Some text here</div>
<button>click</button>
</div>
<div class="arrow-down">
</div>
</div>

CSS border right styling

I want to have a design where my main div(box) will be looking something like below, where i don't want my right top border to be chucked off. Can you please help me in designing the same.
You could use :after pseudo element
div {
width: 250px;
height: 150px;
border: 2px solid #677D50;
border-bottom: 20px solid #677D50;
margin: 50px;
background: white;
position: relative;
}
div:after {
content: '';
position: absolute;
right: 0;
top: 0;
width: 70px;
height: 70px;
background: white;
border-bottom: 2px solid #677D50;
transform: rotate(46deg) translateY(-52px);
}
<div></div>
Or SVG
rect {
fill: #677D50;
}
polygon {
fill: none;
stroke: #677D50;
stroke-width: 2;
stroke-miterlimit: 10;
}
<svg x="0px" y="0px" width="400px" height="250px" viewBox="0 0 400 250">
<polygon points="378,230 24.5,230 24.5,20.5 339,20.5 378,52.5 " />
<rect x="24.5" y="203" width="353.5" height="27" />
</svg>

Centered image over split color background in CSS

I've found how to make an image over color background but not when you have two of them. I'd like to center only one image in the middle of the screen/page and I want it to shrink with the window size.
Image example:
body {
font-family: 'Titillium Web', sans-serif;
}
#top,
#bottom {
background: url('http://uxrepo.com/static/icon-sets/zocial/svg/chrome.svg') no-repeat center center;
background-size: cover;
position: absolute;
left: 0;
right: 0;
height: 50%;
}
#top {
top: 0;
background-color: #ff0000;
}
#bottom {
bottom: 0;
background-color: #fff38f;
}
.header-container {
height: 130px;
width: 100%;
margin: 0 auto;
position: absolute;
top: 130px;
}
.header {
text-align: center;
line-height: 16px;
font-size: 48px;
font-weight: 400;
color: #ffffff;
}
.footer-container {
height: 130px;
width: 99%;
margin: 0 auto;
position: absolute;
bottom: 0;
}
.footer {
text-align: center;
line-height: 16px;
}
.img {
position: absolute;
width: 100%;
}
<body>
<div id="top">
<div class="header-container">
<div class="header">
SOME TITLE
</div>
</div>
</div>
<div id="bottom">
<div class="footer-container">
<div class="footer">
some text
<br>
<br>some text
<br>some text
<br>some text
</div>
</div>
</div>
</body>
Does anyone know how to make this result simple?
CSS Gradient
My approach, with a gradient background: JSFiddle
<div class="background">
<img src="source"/>
</div>
.background{
background: linear-gradient(to bottom, #db6062 0%,#db6062 50%,#db6062 50%,#dae27a 50%,#dae27a 100%);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.background img{
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 200px;
width: 200px;
margin: auto;
}
Svg
Since you are using an svg you can simply use that inline.
And if you put it inline like i have done here in the example below.
You can change all colors in the svg with css.
svg {
height: 100vh;
}
#rect1 {
fill: firebrick;
}
#rect2 {
fill: #229;
}
<div>
<svg viewBox="0 0 500 400">
<rect id="rect1" x="0" y="0" width="1000" height="200" />
<rect id="rect2" x="0" y="200" width="1000" height="200" />
<g transform="translate(150,100) scale(0.2)">
<path d="M0 523q0-75 23-155.5t62-144.5q62-104 182.5-163.5t248.5-59.5q130 0 249.5 81.5t182.5 201.5q50 86 50 214 0 150-71 266t-192 177-270 60q20-36 61-109.5t73.5-130.5 64.5-108l1-2q3-5 12-18.5t12.5-19.5 9.5-17 9.5-21 5.5-21q6-24 6-48 0-80-48-142l275-81q-285 0-428 1-7-1-22-1-99 0-165.5 74t-55.5 173q-2-9-2-28 0-44 15-77l-204-201 198 341q19 72 79.5 117.5t134.5 45.5q17 0 33-3l-66 276q-115 0-223-71t-175-176q-66-102-66-230zm312-19q0 77 54.5 131.5t130.5 54.5 130.5-54.5 54.5-131.5q0-76-54-130.5t-131-54.5-131 54.5-54 130.5z"
/>
</g>
</svg>
</div>