Creating s-shaped curve using css - html

I want to create a curve as shown in below image using css.
I was trying something like this:
.curve {
background-color: #8aa7ca;
height: 65px;
width: 160px;
-moz-border-radius-bottomright: 25px 50px;
border-bottom-right-radius: 25px 50px;
}
<div class="curve">
<p>This is a sample text.</p>
</div>
Please help me

SVG
As Harry suggested in the comments, SVG would be your best option as a double curve in CSS isn't feasible without using multiple elements, pseudo elements or using possibly unsupported CSS3 properties.
SVG stands for Scalable Vector Graphic. The web browser views it as an image but you can add text and normal HTML elements within an SVG.
It is well supported across all browsers as viewable here: CanIUse
<svg width="466" height="603" viewbox="0 0 100 100" preserveAspectRatio="none">
<path d="M0,0
L100,0
C25,50 50,75 0,100z" fill="#8aa7ca" />
</svg>
SVG on MDN
CSS
Ofcourse this is still possible with CSS but does take using pseudo elements :before and :after. It is also not best for the curves as it will render them without anti-aliasing
div {
background: blue;
width: 50px;
height: 75px;
position: relative;
}
div:before {
content: '';
background-image: radial-gradient(circle at 100% 100%, rgba(204, 0, 0, 0) 100px, blue 100px);
position: absolute;
top: 0;
left: 100%;
width: 100px;
height: 75px;
}
div:after {
content: '';
position: absolute;
width: 50px;
height: 75px;
background: blue;
border-radius: 0 0 100% 0 / 0 0 100% 0;
top: 100%;
left: 0;
}
<div></div>

SVG
In svg this can be created using a single path
<svg height="300px" viewBox="0 0 100 100">
<path fill="CornFlowerBlue" d="M0,0
100,0
C50,20 50,80 0,100 Z" />
</svg>

You could make this using pure CSS if you so wished.
Demo
This uses a large box shadow to create the second curve:
.wrap {
position: relative;
height: 400px;
width: 100%;
margin: 0 auto;
max-width: 1024px;
}
.shape {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 50%;
overflow: hidden;
z-index: 10;
}
.shape:after {
content: "";
position: absolute;
top: 10%;
left: 0;
width: 100%;
height: 90%;
border-radius: 0 50% 0 0;
box-shadow: 0 0 0 999px lightgray;
}
.shape2 {
position: absolute;
top: 0;
left: 50%;
height: 100%;
width: 50%;
background: lightgray;
border-radius: 0 0 0 50%;
z-index: 10;
}
/******************************/
html,
body {
margin: 0;
padding: 0;
height: 100%;
vertical-align: top;
overflow: hidden;
background: cornflowerblue;
}
<div class="wrap">
<div class="shape"></div>
<div class="shape2">This will be where you can place the text to go down the right hand side of the slider</div>
</div>

I had a similar requirement but found the CSS for this task to be far too complex for my knowledge level. So, instead, I used an online wave generator.
With that, you can draw the wave you need and generate the SVG.
Then all you have to do is just copy-paste code for the generated wave.
This is the one I used:
svg wage generator

Related

CSS: Can I fit a container to a long/overflowing image?

One of my first css intensive projects, having trouble getting everything lined up how I'd want it to.
How it is and what I want to achieve
The second section is ignoring the overblown 600% image and going right after the previous container (obviously).
I tried setting the .container-stars height to 600%, but that does literally nothing.
Tried using px or vh units, but it messes with the SVG paths, where they ignore the absolute top: 0; and move to the middle (I imagine it's because of the height: 100% somehow, but I can't set it to specific units because then it wouldn't be responsive anymore)
When I set the .container-stars to height: 600vh
.container-stars {
position: relative;
width: 100vw;
height: 100%;
margin-top: 20%;
background: linear-gradient(to bottom, $background 5%, white 40%, transparent 100%, $background 90%);
.path_left {
top: 0;
left: 0;
width: 45%;
height: 100%;
fill: $background;
}
.path_right {
position: absolute;
width: 45%;
height: 100%;
top: 0;
right: 0;
transform: scaleX(-1);
fill: $background;
}
.img_stars {
position: absolute;
background-image: url('/img/stars-1654074_1920.jpg');
top: 0;
left: 0;
width: 100%;
height: 600%;
repeat: repeat-y;
z-index: -1;
}
}
#content {
position: relative;
width: 100vw;
margin-top: 0%;
h2 {
position: absolute;
font-family: $primary-font;
font-size: calc(2vw + 0.5rem);
top: 0;
background: green;
display: block;
transform: translate(0, 50%);
color: #fff;
}
}
<section class="container-stars">
<svg class="path_left" width="450" height="600" viewBox="0 0 450 600">
<path d="M 0 600 C 260 327 202 133 450 0 L 0 0"></path>
</svg>
<svg class="path_right" width="450" height="600" viewBox="0 0 450 600">
<path d="M 0 600 C 260 327 202 133 450 0 L 0 0"></path>
</svg>
<div class="img_stars"></div>
</section>
<section id="content">
<h2>...matter, energy, time and space came into being</h2>
</section>
Would also appreciate any tips if someone has a better way to achieve this.
Troubleshooting whilst trying to maintain responsiveness can really be a pain.

How to draw a drop like shape using CSS?

I want to draw these shapes using CSS and I'm having a bit of trouble
I'm trying the way above:
CSS:
.menu-animation{
border-radius: 50%;
display: inline-block;
height: 40px;
width: 40px;
background-color: #000000;
position: relative;
left: 0px;
}
.menu-animation2{
border-radius: 50%;
display: inline-block;
height: 29px;
width: 23px;
background-color: #000000;
position: absolute;
left: 9px;
top: 26px;
}
If you really want a CSS only solution, you can create black circles with your border-radius: 50%; approach, combine them with a black rectangle and simulate the round cut-out on both sides with white circles. This is how it works:
The single circle elements can be created using the pseudo elements ::before and ::after. With some positioning, the circles position can be adjusted properly.
This is a working example:
.drop {
background: black;
margin: 40px;
height: 20px;
width: 14px;
position: relative;
z-index: 10;
}
.drop::before,
.drop::after {
content: '';
position: absolute;
background: black;
border-radius: 50%;
}
.drop::before {
width: 30px;
height: 30px;
top: -25px;
left: -7px;
}
.drop::after {
width: 20px;
height: 20px;
top: 10px;
left: -3px;
}
.gaps::before,
.gaps::after {
content: '';
position: absolute;
background: white;
border-radius: 50%;
z-index: 10;
}
.gaps::before {
width: 22px;
height: 22px;
top: -3px;
left: -21px;
}
.gaps::after {
width: 22px;
height: 22px;
top: -2px;
left: 13px;
}
<div class="drop">
<div class="gaps"></div>
</div>
Although this is nearly perfect, I would recommend using SVG for this problem, as you can create a smooth outline and you don't have to bother with positioning, sizes and responsive design.
This would be extremely difficult using CSS but there are other solutions. You can attempt to draw them using JavaScript and the HTML5 Canvas element. Or the easier solution would be to create the illustration in a program like Adobe Illustrator, export the image as an SVG file. Get the SVG code from the file (Adobe Illustrator does that for you), it is basically contains the path of the vector. You can then add all the information in an SVG HTML tag and view the element. CSS then allows you to interact with the SVG element.
If you can live with SVG you can do it like this, even animated:
var circle2 = document.getElementById('circle2');
setInterval(function() {
circle2.style.transition="unset";
circle2.style.transform = "translate(0, 0)";
setTimeout(function() {
circle2.style.transition="transform 1400ms ease-in";
circle2.style.transform = "translate(0, 230px)";
}, 0);
}, 1400);
<div style="overflow: hidden">
<svg viewBox="0 0 200 200" width="200" height="200">
<defs>
<filter id="goo-filter">
<feGaussianBlur stdDeviation="8" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" />
</filter>
</defs>
<g fill="black" filter="url(#goo-filter)">
<circle id="circle1" cx="100" cy="40" r="20" />
<circle id="circle2" cx="100" cy="40" r="12" />
</g>
</svg>
<div>

ViewBox issue for SVG responsive button

I'm creating a button with rounded corners using SVG (I have to use SVG).
So I succeed to make it responsive related to his parent element #btnTour which I put a width and a height on. But I always have a gap between this #btnTour and the path of my SVG I think it's related to the viewbox but after reading bunch of articles about it I still can't figured out how to solve my issue.
Thanks for your help.
#btnTour{
display: inline-block;
background: none;
border: none;
outline: none;
position: relative;
margin: 1em;
padding: 0;
width: 192px;
height: 70px;
text-decoration: none;
}
#svgContainer{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 100;
border: dotted 1px red;
}
#btnTourText{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
margin: 0;
text-align: center;
z-index: 100;
font-size: 25px;
color: #2b5e9d;
font-weight: 600;
white-space: nowrap;
}
<a id="btnTour" href="page2.php">
<div id="svgContainer">
<svg width="100%" height="100%" viewBox="0 0 300 125" preserveAspectRatio="none">
<path id="svgBtn" style="fill:none;stroke:#2b5e9d;stroke-width:2;" d="M286.5,62.5C286.5,90.39099999999999,263.891,113,236,113C236,113,171.64499999999998,113,150,113C128.355,113,64,113,64,113C36.109,113,13.5,90.39099999999999,13.5,62.5C13.5,62.5,13.5,62.5,13.5,62.5C13.5,34.609,36.109,12,64,12C64,12,128.35500000000002,12,150,12C171.645,12,236,12,236,12C263.891,12,286.5,34.609,286.5,62.5C286.5,62.5,286.5,62.5,286.5,62.5C286.5,62.5,286.5,62.5,286.5,62.5"></path>
</svg>
</div>
<p id="btnTourText">Go on a Tour</p>
</a>
yes, you have to set the view box to fit the path ( eg. something like viewBox="12.5 11 275 103"); you can do it programmatically via js ( compute the bounding box to the to be fit svg element ) or set/get it from your preferred svg authoring app...

Make HTML/CSS responsive

Due to the skills of others in the community I have created this:
http://codepen.io/anon/pen/NbdoKV
HTML:
.clipboard:after, .clip, .clip:before, .paper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.clipboard {
position: relative;
display: block;
height: 27em;
width: 23em;
margin: 5em auto;
border-radius: 3%;
background: #b69b4c;
}
.clipboard:after {
top: 2.25em;
content: "";
height: 1.5em;
width: 20em;
background: #fefefe;
}
.clip {
z-index: 2;
top: 4.2em;
display: block;
height: 10em;
width: 17em;
border-radius: 50%;
background: #A7A7A7;
}
.clip:before {
content: "";
top: -.5em;
height: 5.3em;
width: 5.3em;
border: 2.2em solid #A7A7A7;
border-radius: 50%;
}
.paper {
z-index: 2;
display: block;
height: 23em;
width: 20em;
margin-top: .5em;
background: #fefefe;
}
.paper:before {
content: "";
position: absolute;
bottom: 0;
right: 0;
height: 3.25em;
width: 3.25em;
}
.paper:after {
content: "";
position: absolute;
height: 1.25em;
width: 1.5em;
}
<i class="clipboard">
<i class="clip"></i>
<i class="paper"></i>
</i>
As you can see this graphic does not scale / respond very well. If I set the width to 100%, everything loses its ratio / perspective. Ideally, I want to be able to set the clipboard width to 100% and everything (height, the clip at top, padding etc) will then scale correctly - much like an image would.
I can see 2 ways of making this responsive:
Changing the HTML/CSS - I have tried and failed
Converting this HTML/CSS to SVG - no idea where to start
How would you make this responsive?
This is an example as svg. There are a few sites where you can draw svgs.
Then you have the paths.
I think the different attributes are self explaining. If you have any questions ask please. I think the best is to read more about this if you want to use it.
Maybe here but there are many more good sources.
<svg height="200" width="450">
<path
id="lineAB"
fill="khaki"
d="M9.778,96h108.445c5.400000000000006,0,9.778000000000006,-4.378,
9.778000000000006,-9.778000000000006v-68.445c0,-5.4,-4.378,-9.778,
-9.778000000000006,-9.778h-108.445c-5.4,0,-9.778,4.378,-9.778,
9.778v68.445c0,5.400000000000006,4.378,9.778000000000006,
9.778,9.778000000000006ZM8,16h112v72h-112v-72Z"
transform="matrix(0.000503985 -1.04456 1.29502 0.000406514 -10.7973 124.73)
translate(-60,150)" />
<path
fill="#C0C0C0"
d="M109.58289641986332,32.006086609509h8v-6.222000000000001c0,-5.3999999999999995,
-4.378,-9.778,-9.778000000000006,-9.778h-30.221999999999994v-6.2219999999999995c0,
-5.4,-4.378,-9.778,-9.778000000000006,-9.778h-20.445c-5.3999999999999995,0,
-9.777999999999999,4.378,-9.777999999999999,9.778v6.222000000000001h-30.222c-5.3999999999999995,
0,-9.778,4.378,-9.778,9.777999999999999v6.222000000000001h112ZM45.58289641986323,
8.006086609509033h24v8h-24v-8Z"
transform="matrix(0.560377 0.00141111 -0.00141111 0.560377 25.8245 -9.95107)
translate(340,90)"/>
Now you only need to adjust the height and with
respectively adding a scale at the transform attribute.

How to transform block in css?

How to transform block in CSS? Pseudo-elements is need or not? I try to create block look like block on the picture below. I can't create such block as on the picture below.
This is my code:
.transform_items {
width: 40%;
height: 80px;
position: relative;
margin: 0 auto;
perspective: 600px;
margin-top: 150px;
left: 50px;
}
.block,
.block::before{
display: block;
position: absolute;
margin: 0 auto;
}
.block {
border: 5px solid transparent;
width: 350px;
height: 60px;
}
.block::before {
content: '';
border: 5px solid #52B352;
transform: rotateY(30deg);
top: -5px;
right: -5px;
bottom: -5px;
left: -35px;
}
.block a {
font-size: 24px;
}
<div class="transform_items">
<div class="block"><a>Block</a></div>
</div>
The expected result:
If you can use SVG (1), it could be like this
codePen
svg #block {
stroke: orange;
fill: none;
stroke-width: 5
}
svg text {
font-size: 25px
}
<svg version="1.1" x="0px" y="0px" width="274px" height="84px" viewBox="0 0 274 84">
<polygon id="block" points="33,13 245,24 245,60 29,64 " />
<text x="100" y="50">BLOCK</text>
</svg>
You can also save the svg code as a .svg file,without the text element, and use it as background-image for the div that contains your text
Read this to learn how to use svg in different ways: https://css-tricks.com/using-svg/
(1) Browser support for SVG is a little better than browser support for transform, caniuse: SVG