I want background shape to include triangle shape and I did it with css. I want that to be responsive in every screen size. I am stuck in this . Any advice ...
header {
width: 100%;
height:150px;
background: #eee;
}
main {
width: 100%;
height:150px;
background: #000;
position:relative;
z-index: 1;
}
main::before {
background: inherit;
top: 0;
content: '';
display: block;
height: 90%;
left: 0;
position: absolute;
right: 0;
transform: skewY(-3deg);
transform-origin: 0;
z-index: -1;
}
main::after {
border-top: 16vh solid blue;
border-left: 50vw solid transparent;
width: 0;
height: 0;
transform: skewY(-3deg);
position: absolute;
content: "";
transform-origin: 0;
right: 0;
top: -10%;
}
<header></header>
<main>
<main>
Expected result in every screen size
You can use clip-path - polygon properties for this.
The issue is, this doesn't support on IE 🤷♂️
More information
Mozilla: https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path
W3Schools: https://www.w3schools.com/cssref/css3_pr_clip-path.asp
CSS Tricks: https://css-tricks.com/almanac/properties/c/clip-path/
main {
position: relative;
width: 100%;
height: 150px;
background: #000;
z-index: 1;
overflow: hidden;
}
main::before,
main::after {
content: '';
position: absolute;
display: block;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 0;
}
main::before {
background-color: #00f;
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 0%);
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 0%);
}
main::after {
background-color: #fff;
-webkit-clip-path: polygon(0 0, 100% 0, 100% 75%, 0 100%);
clip-path: polygon(0 0, 100% 0, 100% 75%, 0 100%);
}
<main><main>
You can try like below:
html::before {
content: "";
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 60vh;
transform-origin: right;
transform: skewY(-5deg);
background: linear-gradient(-160deg, blue 15vw, #000 15.2vw);
}
I really dont want to answer my own question though, I have been research for about two days and I found something really effective solution. So let me post it .
If I have modify a little bit on main::after property , it can be show responsively now.
transform-origin: 0; to transform-origin: -99%;
top: -10% to top: 0
That is...
Related
I'm trying to create this icon using pure css & a single div
so far I've only managed to add 2 points like this:
:root {
--gear_radius: 5rem;
--gear_color: black;
--gear_thickness: 1.5rem;
--gear_pin_length: 1.5rem;
--gear_pin_gap: 1.5rem;
}
.gear {
margin: 5rem;
height: var(--gear_radius);
width: var(--gear_radius);
border-radius: 50%;
border: var(--gear_color) var(--gear_thickness) solid;
box-sizing: border-box;
position: relative;
}
.gear:before {
position: absolute;
content: "";
display: block;
height: var(--gear_pin_length);
width: var(--gear_thickness);
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(45deg);
box-shadow: 0 calc(var(--gear_thickness) * 2) 0 0 black, 0 calc(var(--gear_thickness) * -2) 0 0 black;
}
.gear:after {
position: absolute;
content: "";
display: block;
height: var(--gear_pin_length);
width: var(--gear_thickness);
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
box-shadow: 0 calc(var(--gear_thickness) * 2) 0 0 black, 0 calc(var(--gear_thickness) * -2) 0 0 black;
}
<div class="gear"></div>
How do I add 2 more points at the top and bottom? I don't know what approach to take from here?
The original picture of a gear wheel has an angle to the sides of each tooth.
However, I notice that in your part-solution you aren't worried about that and have parallel edges.
Here's a snippet that puts in all 6 teeth with parallel edges.
It uses before and after pseudo elements which had stripes as background and are rotated. The main div also has a stripe for a background but additionally a radial gradient with white and black circles.
.cog {
width: 30vmin;
height: 30vmin;
position: relative;
background-image: radial-gradient(white 0 35%, black 35% 70%, transparent 70% 100%), linear-gradient(to right, black, black);
background-size: 70% 70%, 25% 100%;
}
.cog::before,
.cog::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(to right, black, black);
background-size: 25% 100%;
z-index: -1;
}
.cog,
.cog::before,
.cog::after {
background-repeat: no-repeat;
background-position: center center;
transform-origin: center;
}
.cog::before {
transform: rotate(60deg);
}
.cog::after {
transform: rotate(120deg);
}
<div class="cog"></div>
Here's what it produces:
To get more sophisticated shape - such as the slope on the teeth, you could do more with gradients or just CSS clip-path (though by the time you've done this you probably might as well have created an SVG).
Well, of course SVG is better, but since your question is more of a challenge, here is my solution:
* {
margin: 0;
padding: 0;
}
.icon {
position: relative;
background: beige;
height: 160px;
width: 160px;
}
.wheel {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width: 32px;
height: 32px;
background: beige;
border-radius: 50%;
border: solid 24px brown;
}
.cog {
position: absolute;
width: 24px;
height: 120px;
border-radius: 6px;
background: brown;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
.cog:nth-child(2) {
transform: rotate(45deg);
}
.cog:nth-child(3) {
transform: rotate(90deg)
}
.cog:nth-child(4) {
transform: rotate(135deg)
}
<div class="icon">
<div class="cogs">
<div class="cog"></div>
<div class="cog"></div>
<div class="cog"></div>
<div class="cog"></div>
</div>
<div class="wheel"></div>
<div>
I have a simple 100vw-100vh page with 3 images in the background for mobile, and 5 in a different set-up for larger viewports.
The way I have it set-up so far:
3 (or 5) div containers, clipped as a polygon in CSS
the images set as background-image of each container in CSS, with background-size: cover.
This works fine to display the images, but when I try to add borders to the containers the clipped sides won't get the border, only the "original" bits would (as in, of the sides of the rectangles before clipping).
Is there a way to add them all around?
Note: I have played with background-origin without result. The whole page is set-up with box-sizing: border-box; but it does not seem to impact the result either.
Codepen of my code, for the mobile version (3 images) below.
Many thanks for your help!
PS: I have seen a couple of posts related to the topic to an extent, but not with the background image set-up the same way, and as they were all a bit old I thought wider browser support may help #hope. Sorry for any redundancy I would have missed!
https://codepen.io/aguafresca/pen/abNvyXO?editors=1100
<body> <main>
<welcome-page>
<contacto-link>
<p>contact details</p>
</contacto-link>
</welcome-page>
<background-container id="cont1" class=""></background-container>
<background-container id="cont2" class=""></background-container>
<background-container id="cont3"></background-container>
</main> </body>
CSS:
/* general set-up */
html {
width: 100vw;
height: 100vh;
box-sizing: border-box;
}
*, *:before, *:after, a, main, body {
box-sizing: inherit;
margin: 0;
padding: 0;
}
/* setting-up the background */
welcome-page {
z-index: 2;
height: 100vh;
width: 100vw;
position: absolute;
top:0;
left:0;
background-color: rgba(255, 255, 255, 0.3);
}
background-container {
display: block;
z-index: 1;
position: absolute;
background-color: dimgray;
background-size: cover;
border: red solid 3px;
background-origin: content-box;
}
#cont1 {
top: 0;
left: 0;
height: 60vh;
width: 70vw;
clip-path: polygon(0 0, 100% 0, 0 100%);
background-image: url("https://images.unsplash.com/photo-1596072181334-1adc75da7717?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ");
}
#cont2 {
top: 0;
left: 0;
height: 100vh;
width: 100vw;
clip-path: polygon(70% 0, 100% 0, 100% 40%, 30% 100%, 0 100%, 0 60%);
background-image: url("https://images.unsplash.com/photo-1595680337986-ce4862b497b9?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ");
}
#cont3 {
bottom: 0;
right: 0;
height: 60vh;
width: 70vw;
clip-path: polygon(100% 0, 100% 100%, 0 100%);
background-image: url("https://images.unsplash.com/photo-1595035848637-29bd22af4faf?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ");
border-color: green;
z-index:10;
}
/* footer format */
contacto-link {
display: block;
position: fixed;
bottom: 0;
height: 5vh;
width:100vw;
line-height: 5vh;
background-color: rgba(255, 255, 255, 0.8);
color: dimgrey;
}
Using an extra wrapper you can consider drop-shadow to simulate the borders.
Here is an example where I will not really and an extra wrapper but I will use pseudo element for the image:
body {
margin: 3px;
height: calc(100vh - 6px);
position: relative;
}
.background-container {
z-index: 1;
position: absolute;
filter:
drop-shadow(0px 3px 0px red)
drop-shadow(3px 0px 0px red)
drop-shadow(0px -3px 0px red)
drop-shadow(-3px 0px 0px red)
}
.background-container::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-size: cover;
}
#cont1 {
top: 0;
left: 0;
height: 60%;
width: 70%;
}
#cont1::before {
clip-path: polygon(0 0, 100% 0, 0 100%);
background-image: url("https://picsum.photos/id/10/800/800");
}
#cont2 {
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index:2;
}
#cont2::before {
clip-path: polygon(70% 0, 100% 0, 100% 40%, 30% 100%, 0 100%, 0 60%);
background-image: url("https://picsum.photos/id/1011/800/800");
}
#cont3 {
bottom: 0;
right: 0;
height: 60%;
width: 70%;
}
#cont3::before {
clip-path: polygon(100% 0, 100% 100%, 0 100%);
background-image: url("https://picsum.photos/id/1074/800/800");
}
<div class="background-container" id="cont1"></div>
<div class="background-container" id="cont2"></div>
<div class="background-container" id="cont3"></div>
And with different coloration:
body {
margin: 3px;
height: calc(100vh - 6px);
position: relative;
}
.background-container {
z-index: 1;
position: absolute;
filter:
drop-shadow(0px 3px 0px var(--c,red))
drop-shadow(3px 0px 0px var(--c,red))
drop-shadow(0px -3px 0px var(--c,red))
drop-shadow(-3px 0px 0px var(--c,red))
}
.background-container::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-size: cover;
}
#cont1 {
top: 0;
left: 0;
height: 60%;
width: 70%;
--c:blue;
}
#cont1::before {
clip-path: polygon(0 0, 100% 0, 0 100%);
background-image: url("https://picsum.photos/id/10/800/800");
}
#cont2 {
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index:2;
}
#cont2::before {
clip-path: polygon(70% 0, 100% 0, 100% 40%, 30% 100%, 0 100%, 0 60%);
background-image: url("https://picsum.photos/id/1011/800/800");
}
#cont3 {
bottom: 0;
right: 0;
height: 60%;
width: 70%;
--c:yellow;
}
#cont3::before {
clip-path: polygon(100% 0, 100% 100%, 0 100%);
background-image: url("https://picsum.photos/id/1074/800/800");
}
<div class="background-container" id="cont1"></div>
<div class="background-container" id="cont2"></div>
<div class="background-container" id="cont3"></div>
http://jsfiddle.net/VpW5x/1141/
.one-line {
position: relative;
}
.one-line:after {
content: '';
position: absolute;
top: 0;
bottom: 0;
width: 25px;
background: red;
clip-path: polygon(100% 50%, 0 0, 0 100%);
left: 100%;
}
How to make the right arrow appear after the text, even if the text is really long like in the example?
use this css will help you
.one-line {
position: relative;
display:inline-block;
vertical-align:top;
}
.one-line:after {
content: '';
position: absolute;
top: 0;
bottom: 0;
width: 25px;
background: red;
clip-path: polygon(100% 50%, 0 0, 0 100%);
left: 100%;
}
I am trying to clip a triangle inside a div .box-inner-2 and mask the outside of that to look like:
but what I am getting now is this. Can you please let me know how to do this?
.wrapper{
position: relative;
height: 250px;
width: 250px;
}
.box-inner-1{
position: absolute;
top:0;
left: 0;
right: 0;
bottom: 0;
background-color: red;
}
.box-inner-2{
position: absolute;
top:0;
left: 0;
right: 0;
bottom: 0;
background-color: white;
clip-path: polygon(10% 0, 0 20%, 20% 20%);
}
<div class="wrapper">
<div class="box-inner-1"></div>
<div class="box-inner-2"></div>
</div>
So here is a brief of what I changed in your code:
Moved the triangle clip-path: polygon(10% 0, 0 20%, 20% 20%) to the box-inner-1 (adjusted top and left for illustration)
Added an inset clip-path to the box-inner-2 and a psuedo after element to clip the triangle.
See demo below:
.wrapper {
position: relative;
height: 250px;
width: 250px;
border: 2px solid;
}
.wrapper:after {
content: '';
clip-path: inset(0% 94% 0% 0%);
background: #fff;
display: block;
height: 100%;
}
.box-inner-1 {
position: absolute;
top: 10px;
left: 10px;
right: 0;
bottom: 0;
background-color: red;
clip-path: polygon(10% 0, 0 20%, 20% 20%);
}
.box-inner-2 {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
clip-path: inset(0% 0% 93% 0%);
}
<div class="wrapper">
<div class="box-inner-1"></div>
<div class="box-inner-2"></div>
</div>
I am trying to take this css Octagon and give it a solid red border. However, when i add the border it only works on portion of the shape. Does anyone have a solution for this?
Here is a JS FIDDLE
HTML
<div class='octagonWrap'>
<div class='octagon'></div>
</div>
CSS
.octagonWrap{
width:200px;
height:200px;
float: left;
position: relative;
}
.octagon{
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
overflow: hidden;
}
.octagon:before {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
transform: rotate(45deg);
background: #777;
content: '';
border: 3px solid red;
}
You can modify your own code to work with this. Right now, you have rules for .octagon that should be for .octagon-wrapper, and rules for .octagon::before that should be for .octagon. Just shift the CSS rules and have them apply to their parents, while changing the border property of .octagon::before to inherit from .octagon.
.octagonWrap {
width:200px;
height:200px;
float: left;
position: relative;
overflow: hidden;
}
.octagon {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
overflow: hidden;
transform: rotate(45deg);
background: #777;
border: 3px solid red;
}
.octagon:before {
position: absolute;
/* There needs to be a negative value here to cancel
* out the width of the border. It's currently -3px,
* but if the border were 5px, then it'd be -5px.
*/
top: -3px; right: -3px; bottom: -3px; left: -3px;
transform: rotate(45deg);
content: '';
border: inherit;
}
<div class='octagonWrap'>
<div class='octagon'></div>
</div>
SVG solution
I do not know if using svg is an option,
If it is here is how simple it is done.
<svg viewBox="0 0 75 75" width="200px">
<path d="m5,22 18,-18 28,0 18,18 0,28 -18,18, -28,0 -18,-18z" stroke="red" stroke-width="2" fill="black" />
</svg>
You could use an online calculator (or calculate it manually) to compute the size in which the ratio of the side, and overall height needs to be.
Then by using some pseudos and a span element, you could create this shape via:
.oct {
height: 241px;
width: 100px;
background: none;
position: relative;
-webkit-box-sizing: border-box;
box-sizing: border-box;
border-top: 10px solid tomato;
border-bottom: 10px solid tomato;
margin: 100px auto;
transition: all 0.8s;
}
.oct:before,
.oct:after,
.oct span {
content: "";
position: absolute;
height: inherit;
width: inherit;
background: inherit;
-webkit-box-sizing: inherit;
box-sizing: inherit;
border: inherit;
top: -10px;
z-index:-1;
}
.oct:before {
left: -100%;
transform: rotate(-45deg);
transform-origin: top right;
}
.oct:after {
left: 100%;
transform: rotate(45deg);
transform-origin: top left;
}
.oct span {
height: inherit;
width: inherit;
background: inherit;
transform: rotate(90deg);
}
.oct:hover {
transform: rotate(180deg);
}
<div class="oct">
<span></span>
</div>
You can do that very effectively with clip-path
.octagonWrap {
background: red;
width: 200px;
height: 200px;
position: absolute;
-webkit-clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}
.octagon {
position: relative;
background: gray;
width: 190px;
height: 190px;
top: 5px;
left: 5px;
-webkit-clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}
<div class="octagonWrap">
<div class='octagon'></div>
</div>
Imagine those red lines extending until they touch each other. That square (rotated 45%) has a complete border, you just don't see the "cut off" corners due to the overflow: hidden;
This seems to work (but does so by adding two extra divs, so there may be a better way):
<div class='octagonWrap'>
<div class='octagon'></div>
<div class='vert'> </div>
<div class='hort'> </div>
</div>
and then add tihs css:
.vert {
position: absolute;
left: 60px;
border-top: 3px solid red;
border-bottom: 3px solid red;
height: 194px;
width: 80px;
}
.hort {
position: absolute;
top: 60px;
border-left: 3px solid red;
border-right: 3px solid red;
width: 94px;
height: 80px;
}
You should try using the HTML5 canvas element. You should be able to draw the polygon and then add a stroke to it.