Create a Shape ONLY with CSS - css

I need to create this custom shape with only CSS3.
Need to be with CSS, not svg.
I was trying to use the snippets of this link: Wave (or shape?) with border on CSS3 but i don't know how to manipulate shapes properly.
Also can be only the center shape! I'm testing with this pen: https://codepen.io/Blumenkranz/pen/vYEeLjr
#mixin push--auto {
margin: {
left: auto;
right: auto;
}
}
#mixin pseudo($display: block, $pos: absolute, $content: "") {
content: $content;
display: $display;
position: $pos;
}
.section {
width: 100%;
height: 50vh;
background: $blue-dark;
position:relative;
&::after, &::before {
#include pseudo;
#include push--auto;
bottom: -46px;
left: 35%;
width: 250px;
height: 150px;
background: $blue-dark;
border-radius: 100%;
}
}

I don't know why you want to make this using only css, as svg would be much simpler, but here you go. I made an approximation of your shape, which you can easily adjust, using a similar technique to the one you linked.
Here is the code. I'm using display flex on the body and margin auto on the container to position it in the center of the page for display purposes.
body {
display: flex;
height: 100vh;
}
.container {
margin: auto;
position: relative;
}
.shape {
width: 200px;
height: 200px;
background-color: #157995;
transform: rotate(45deg) skew(-10deg,-10deg);
clip-path: polygon(68% 100%, 100% 68%, 100% 100%);
border-radius: 15%;
}
.bar {
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
width: 80%;
height: 12px;
background-color: #157995;
}
.container::before, .container::after {
content: "";
position: absolute;
width: 50px;
height: 20px;
background-color: white;
z-index: 1;
bottom: 0px;
}
.container::before {
left: 12.4px;
border-top-right-radius: 50%;
transform: skew(55deg);
}
.container::after {
right: 12.4px;
border-top-left-radius: 50%;
transform: skew(-55deg);
}
<!DOCTYPE html>
<html>
<body>
<div class="container">
<div class="bar"></div>
<div class="shape"></div>
</div>
</body>
</html>

A little bit late to the party here, but this was my effort using:
a transparent container (with a visible top border)
two background-coloured pseudo-elements inside the transparent container
a slim horizontal rectangle; and
a circle
Working Example:
.line {
position: relative;
height: 30px;
border-top: 1px solid rgb(0, 123, 149);
overflow: hidden;
}
.circle {
position: absolute;
top: -80px;
left: calc(50% - 50px);
width: 100px;
height: 100px;
background-color: rgb(0, 123, 149);
border-radius: 50%;
}
.rectangle {
position: absolute;
top: -1px;
left: calc(50% - 64px);
width: 128px;
height: 12px;
background-color: rgb(0, 123, 149);
}
.line::before,
.line::after {
content: '';
position: absolute;
top: -1px;
z-index: 24;
width: 100px;
height: 100px;
border-radius: 50%;
background-color: rgb(255, 255, 255);
}
.line::before {
left: calc(50% - 110px);
}
.line::after {
right: calc(50% - 110px);
}
<div class="line">
<div class="rectangle"></div>
<div class="circle"></div>
</div>

Related

How to remove borders under play button and logo img in CSS?

How to remove borders under play button and around logo img in CSS?
How to remove borders under play button and around logo img in CSS?
How to remove borders under play button and around logo img in CSS?
How to remove borders under play button and around logo img in CSS?
How to remove borders under play button and around logo img in CSS?
.fullscreen {
height: 100%;
width: 100%;
background: no-repeat url('https://www.planetware.com/wpimages/2019/10/switzerland-in-pictures-most-beautiful-places-matterhorn.jpg') center / cover;
}
.line_horiz {
position: absolute;
width: 3px;
height: 100%;
background-color: rgba(255, 255, 255, 1);
top: 0;
left: 50%;
}
.line_vert {
position: absolute;
width: 100%;
height: 3px;
background-color: rgba(255, 255, 255, 1);
top: 20%;
left: 0;
}
.logo-img {
position: absolute;
width: 100px;
height: 100px;
border: 3px solid #ffffff;
background: #ffffff;
transform: translate(-50%, -50%);
top: 20%;
left: 50%;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
}
.btn {
position: absolute;
width: 100px;
height: 100px;
border: 3px solid #ffffff;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
z-index: 1;
}
.btn::after {
content: '';
display: block;
width: 60px;
height: 60px;
background: #ffffff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="fullscreen">
<span class="line_vert"></span>
<span class="line_horiz"></span>
<div class="logo-img">Logo img</div>
<div class="btn"></div>
</div>
As the horizontal and vertical lines are styling rather than informational content one suggestion is to remove them from the body of the HTML and instead create them using linear gradients on the background of the fullscreen element. That way they don't for example get looked at by screen readers. Also, using linear gradients means we can have 'gaps' in the lines where we want them.
This snippet just does the calculation of the gap for the btn element as the logo element has background white so it doesn't matter that the 'line' goes right across. If this changes then put in a linear gradient with gap calculations in a similar way to that done for the btn.
Note, box-sizing with content has been used and explicitly stated (so borders are included in the calculations and padding is set to zero) in case it has been altered elsewhere in the code.
body {
width: 100vw;
height: 100vh;
}
.fullscreen {
/* set up some variables to make it easier to change things later if you want to */
--logoMid: calc(20% - var(--borderW));
--btnW: 100px;
--btnMid: 50%;
/* position from the top to the middle of the btn */
--borderW: 3px;
--btnTop: calc(var(--btnMid) - (var(--btnW) / 2) - (var(--borderW) / 2));
/* actual position of top of btn element */
--btnBottom: calc(var(--btnTop) + var(--btnW) + var(--borderW));
box-sizing: content-box;
height: 100%;
width: 100%;
background-image: linear-gradient(white 0%, white var(--btnTop), transparent var(--btnTop), transparent var(--btnBottom), white var(--btnBottom), white 100%), linear-gradient(to right, white 0, white 100%), url('https://www.planetware.com/wpimages/2019/10/switzerland-in-pictures-most-beautiful-places-matterhorn.jpg');
background-size: var(--borderW) 100%, 100% var(--borderW), cover;
background-position: calc(var(--btnMid) - (var(--borderW) / 2)) 0, 0 var(--logoMid), center top;
background-repeat: no-repeat no-repeat;
margin: 0;
padding: 0;
position: relative;
}
.logo-img {
box-sizing: content-box;
position: absolute;
width: 100px;
height: 100px;
border: 3px solid #ffffff;
background: #ffffff;
transform: translate(-50%, -50%);
top: 20%;
left: 50%;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
margin: 0;
padding: 0;
}
.btn {
box-sizing: content-box;
margin: 0;
padding: 0;
position: absolute;
width: 100px;
height: 100px;
border: 3px solid #ffffff;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
z-index: 1;
}
.btn::after {
box-sizing: content-box;
content: '';
display: block;
width: 60px;
height: 60px;
background: #ffffff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="fullscreen">
<div class="logo-img">Logo img</div>
<div class="btn"></div>
</div>
Note: run the snippet in full screen as there won't be enough room to show the gap between the logo and btn on the small snippet viewport.
Here is my solution, Its not perfect, but it will give you a good starting points.
I have changes your HTML structure, by removing the divs that create the lines, Instead, I have used pseudo selectors to draw the lines.
Note that, you will have to tweak some of these numbers to properly fit your content.
Please run the example in full screen mode
.fullscreen {
height: 100vh;
width: 100%;
background: no-repeat url("https://www.planetware.com/wpimages/2019/10/switzerland-in-pictures-most-beautiful-places-matterhorn.jpg") center/cover;
}
.logo-img {
position: absolute;
width: 100px;
height: 100px;
border: 3px solid #ffffff;
background: #ffffff;
transform: translate(-50%, -50%);
top: 100px;
left: 50%;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
}
.logo-img:before {
content: "";
position: absolute;
height: 3px;
width: calc(50vw - 90px);
background-color: #ffffff;
top: 50%;
left: 130px;
display: block;
}
.logo-img:after {
content: "";
position: absolute;
height: 3px;
width: calc(50vw - 90px);
background-color: #ffffff;
top: 50%;
right: 130px;
display: block;
}
.btn {
position: absolute;
width: 100px;
height: 100px;
border: 3px solid #ffffff;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
z-index: 1;
padding: 20px;
box-sizing: border-box;
}
.btn .inner {
width: 100%;
height: 100%;
background: white;
}
.btn:after {
content: "";
display: block;
width: 3px;
height: calc(50vh - 48px);
background: #ffffff;
position: absolute;
top: 100%;
left: 50%;
}
.btn:before {
content: "";
display: block;
width: 3px;
top: calc(-50vh + 220px);
background: #ffffff;
position: absolute;
bottom: 100%;
left: 50%;
}
<div class="fullscreen">
<div class="logo-img">Logo img</div>
<div class="btn">
<div class="inner"></div>
</div>
</div>

Two diagonal div slips with CSS

I'm trying to create a background with two diagonal splits, with one over the other one.
I tried using two linear-gradient on the background but it didn't work.
Any can help me solve this with CSS?
This can be done using linear-gradient background images but it would need gradients instead of just one.
.diagonal-background {
height: 200px;
width: 200px;
background: linear-gradient(to bottom left, transparent 50%, #EEE 50.5%),
linear-gradient(to bottom right, transparent 50%, #CCC 50.5%);
/* just for demo */
line-height: 200px;
text-align: center;
}
<div class='diagonal-background'>
Some content</div>
1- You can do this (adjust your needs):
CSS
div {
display: inline-block;
background: #FCFCFE;
position: relative;
width: 200px;
height: 200px;
overflow: hidden;
}
.bg1 {
position: absolute;
top: 50px;
display: inline-block;
transform: rotate(45deg);
width: 300px;
height: 300px;
left: -160px;
background: #F8F7FA;
z-index: 1;
}
.bg2 {
position: absolute;
top: 50px;
display: inline-block;
transform: rotate(-45deg);
width: 300px;
height: 300px;
right: -160px;
background: #F2F3F6;
z-index: 1;
}
HTML
<div>
<div class="bg2"></div>
<div class="bg1"></div>
</div>
DEMO HERE
2- Or you can use pseudo elements (adjust your needs):
CSS
div {
display: inline-block;
background: #FCFCFE;
position: relative;
width: 200px;
height: 200px;
overflow: hidden;
}
div:after {
position: absolute;
content:"";
top: 50px;
display: inline-block;
transform: rotate(45deg);
width: 300px;
height: 300px;
left: -160px;
background: #F8F7FA;
z-index: 1;
}
div:before{
position: absolute;
content:"";
top: 50px;
display: inline-block;
transform: rotate(-45deg);
width: 300px;
height: 300px;
right: -160px;
background: #F2F3F6;
z-index: 1;
}
HTML
<div></div>
DEMO HERE

Creating a curved shadow with a color gradient

Here is a shadow that I am trying to replicate using just CSS and I just cannot work out how to do it. I have spent hours trying. I think I need to create 2 shadow elements but I'm not sure how to proceed.
The closest thing I get is with this (an abysmal attempt - I know):
.type-product:before, .type-product:after{
z-index: -1;
position: absolute;
content: "";
bottom: 25px;
left: 21px;
width: 50%;
top: 80%;
max-width:300px;
background: #777;
box-shadow: 0 35px 20px #777;
transform: rotate(-8deg);
}
.type-product:after{
transform: rotate(8deg);
right: 20px;
left: auto;
}
Most appreciative if any CSS gurus could provide any help.
NOTE: I don't think that this link covers my problem fully. It just discusses the curve - whilst I need a curve with a color-gradient...
To me that looks like something that can be achieved using a couple of elements like shown below. The shadow is actually a linear-gradient on top of which a white circle is placed. The drawback of this approach is that it would work only with a solid background (because the circle that is overlayed would need a solid color).
That just doesn't look like it could be possible using a box-shadow because the shadow itself seems like a gradient which goes from transparent or white on the left to black in the middle to transparent or white again on the right.
The output is responsive and can adapt itself to all dimensions of the parent container. Just :hover the container in the snippet to see it in action :)
.wrapper {
position: relative;
height: 200px;
width: 200px;
overflow: hidden;
}
.content {
height: 85%;
width: 100%;
border: 1px solid;
}
.wrapper:before {
position: absolute;
content: '';
bottom: 0px;
left: 0px;
height: 15%;
width: 100%;
background: linear-gradient(to right, transparent 2%, #444, transparent 98%);
}
.wrapper:after {
position: absolute;
content: '';
bottom: -186%;
/* height of before - height of after - 1% buffer for the small gap */
left: -50%;
height: 200%;
width: 200%;
border-radius: 50%;
background: white;
}
* {
box-sizing: border-box;
}
/* just for demo */
.wrapper {
transition: all 1s;
}
.wrapper:hover {
height: 300px;
width: 400px;
}
<div class='wrapper'>
<div class='content'></div>
</div>
You can do this with :before pseudo element and box-shadow
div {
width: 200px;
height: 100px;
border: 1px solid #aaa;
position: relative;
background: white;
}
div:before {
content: '';
border-radius: 50%;
height: 100%;
width: 100%;
position: absolute;
z-index: -1;
left: 0;
transform: translateY(103%);
box-shadow: 0px -54px 13px -47px #000000, -4px -45px 35px -28px #999999;
}
<div></div>
Aside from the answers, this could also be a good box shadow for your class as well. (This is just preference & similar to what you want).
.box {
width: 70%;
height: 200px;
background: #FFF;
margin: 40px auto;
}
.type-product {
position: relative;
}
.type-product:before {
z-index: -1;
position: absolute;
content: "";
bottom: 17px;
left: 10px;
width: 50%;
top: 70%;
max-width: 300px;
background: #777;
box-shadow: 0 18px 20px #777;
transform: rotate(-8deg);
}
.type-product:after {
z-index: -1;
position: absolute;
content: "";
bottom: 17px;
right: 10px;
width: 50%;
top: 80%;
max-width: 300px;
background: #777;
box-shadow: 0 18px 20px #777;
transform: rotate(8deg);
}
<div class="type-product box">
</div>
Hope you like it.

Recreate this radial image using css

I would like to know if it's possible to recreate the following image using css.
I am currently using it but in svg format.
Imagine this:
jsfiddle link
#circle {
background: #ccc;
border-radius: 50%;
/* Change these two equally to change circle size. Can be pixels, too. */
width: 25%;
padding-top: 25%;
height: 0;
position: relative;
}
.hand {
background: black;
width: 1px;
height: 100%;
position: absolute;
left: 50%;
top: 0;
}
.hand:nth-child(2) {
transform: rotate(90deg);
}
.hand:nth-child(3) {
transform: rotate(45deg);
}
.hand:nth-child(4) {
transform: rotate(135deg);
}
#circle:after {
content: '';
display: block;
width: 80%;
height: 80%;
border-radius: 50%;
background: white;
position: absolute;
top: 10%;
left: 10%;
}
<div id="circle">
<div class="hand"></div>
<div class="hand"></div>
<div class="hand"></div>
<div class="hand"></div>
</div>
Or if you need the middle to be transparent (this is a little hacky, and you may have to modify it to fit your exact needs): https://jsfiddle.net/wdoe8r3m/1/

Create a cross shape in CSS

IS it possible, I know all the following shapes are possible in this link:
http://css-tricks.com/examples/ShapesOfCSS/
but cross must be possible too. When I say cross I mean like this:
You could achieve something like this with pseudoelements only:
http://jsbin.com/upiyoc/1/edit
#cross {
width: 100px;
height: 100px;
position: relative;
}
#cross:before, #cross:after {
content: "";
position: absolute;
z-index: -1;
background: #d00;
}
#cross:before {
left: 50%;
width: 30%;
margin-left: -15%;
height: 100%;
}
#cross:after {
top: 50%;
height: 30%;
margin-top: -15%;
width: 100%;
}
The size of the cross will proportionally scale, according to the width and height of the #cross element
Update: another solution (using less code) could simply involve multiple linear-gradients (without pseudolements) e.g.
http://codepen.io/anon/pen/zxwgPo
#cross {
width: 100px;
height: 100px;
background: linear-gradient(to bottom, transparent 35%,
#d00 35%,
#d00 65%,
transparent 65%),
linear-gradient(to right, transparent 35%,
#d00 35%,
#d00 65%,
transparent 65%),
}
Of course it is. You just have to use two elements : See http://jsfiddle.net/92XTx/2/
The enclosing div is relatively positioned so that both children can be absolutely positioned.
#cross {
position: relative;
width: 150px;
height: 150px;
}
Here they are both absolutely positioned:
#cross div {
position: absolute;
background: red;
}
to make them superpose.
And then create your shapes:
.cross-vertical {
left: 33%;
width: 33%;
height: 100%;
}
.cross-horizontal {
top: 33%;
width: 100%;
height: 33%;
}
Because all the answers I see here look either lengthy or vendor-prefix-dependent,
#cross {
background: red;
height: 100px;
position: relative;
left: 50px;
width: 20px;
}
#cross:after {
background: red;
content: "";
height: 20px;
left: -40px;
position: absolute;
top: 40px;
width: 100px;
}
<div id="cross"></div>
This can be done with a regular '+' plus character together with a text-stroke
DEMO (Webkit,Android only)
div {
font-size: 80px;
-webkit-text-stroke: 20px red;
display: inline-block;
padding: 0 20px;
}
<div>+</div>
CSS Transform can be easily used to achieve plus shape
.close {
position: absolute;
right: 10px;
top: 6px;
width: 20px;
height: 20px;
opacity: 0.3;
}
.cross:before, .cross:after {
position: absolute;
left: 15px;
content: ' ';
height: 21px;
width: 2px;
background-color: #333;
}
.cross:before {
transform: rotate(0deg);
}
.cross:after {
transform: rotate(-90deg);
}

Resources