CSS shape something like tea drop - css

I am trying to create this shape ( on the uploaded image ) only with css borders but I have problem with the corners they are not accepting the right shape. May I ask you guys for advice or best practice how to create it ?
Here is my code
.tea-drop {
width: 90px;
height: 25px;
display: block;
background: #000;
border-top-left-radius: 100%;
border-top-right-radius: 60%;
border-bottom-left-radius: 70%;
border-bottom-right-radius: 67%;
}
<div class="tea-drop"></div>

SVG is the recommended way to create such shapes. It offers simplicity and scale-ability.
We can use SVG's path element to create a shape like above and fill it with some solid color, gradient or a pattern.
Only one attribute d is used to define shapes in path element. This attribute itself contains a number of short commands and few parameters that are necessary for those commands to work.
Following code will create above shape:
<path d="M 0,0
C 100,10 120,150 60,75
Z" />
Below is a brief description of path commands used in above code:
M command is used to define the starting point. It appears at the beginning and specify the point from where drawing should start.
Q command is used to draw curves.
Z command is used to close current path. It draws a straight line from current point to the starting point to close the shape.
Output Image:
Working Example:
* {box-sizing: border-box;}
body {
background: linear-gradient(teal, skyblue);
text-align: center;
min-height: 100vh;
padding: 10px;
margin: 0;
}
<svg width="200" height="200" viewBox="0 0 100 100">
<path d="M0,0
C 100,10 120,150 60,75
Z" />
</svg>
This shape can be filled with gradient or pattern as well. <linearGradient> element is used to define a gradient in SVG. This element can then be referenced later using an id attribute to fill or outline any shape.
<linearGradient id="grad" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="orange" />
<stop offset="1" stop-color="green" />
</linearGradient>
The direction of the gradient is controlled by the x1, y1, x2 and y2 while <stop> elements are used to define colors and their position along the gradient line.
Output Image:
Working Example:
* {box-sizing: border-box;}
body {
background: linear-gradient(teal, skyblue);
text-align: center;
min-height: 100vh;
padding: 10px;
margin: 0;
}
<svg width="200" height="200" viewBox="0 0 100 100">
<defs>
<linearGradient id="grad" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="orange" />
<stop offset="1" stop-color="green" />
</linearGradient>
</defs>
<path d="M0,0
C 100,10 120,150 60,75
Z" fill="url('#grad')" />
</svg>
We can even apply shadow to this shape using SVG's filters. This article on MDN explains the basics of filters.
Output Image:
Working Example:
* {box-sizing: border-box;}
body {
background: linear-gradient(teal, skyblue);
text-align: center;
min-height: 100vh;
padding: 10px;
margin: 0;
}
<svg width="240" height="240" viewBox="0 0 120 120">
<defs>
<linearGradient id="grad" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="orange" />
<stop offset="1" stop-color="green" />
</linearGradient>
<filter id="shadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<path d="M10,10
C 110,20 130,160 70,85
Z" fill="url('#grad')" filter="url('#shadow')" />
</svg>
Useful Resources:
Below are some useful links for SVG:
Specification
MDN

You can use CSS3 to make that.
.tear {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
width: 10em;
height: 10em;
border: none;
-webkit-border-radius: 80% 0 55% 50% / 55% 0 80% 50%;
border-radius: 80% 0 55% 50% / 55% 0 80% 50%;
font: normal 100%/normal Arial, Helvetica, sans-serif;
color: rgba(0,0,0,1);
-o-text-overflow: clip;
text-overflow: clip;
background: rgb(0,0,0);
-webkit-transform: rotateX(42.5447924299deg) rotateY(100deg) rotateZ(-45.26deg) translateY(1px) ;
transform: rotateX(42.5447924299deg) rotateY(100deg) rotateZ(-45.26deg) translateY(1px) ;
-webkit-transform-origin: 50% 0 0;
transform-origin: 50% 0 0;
}
<div class="tear"></div>
Reference: http://enjoycss.com/SfB
I saved the link, you can customized it for yourself.

Related

How to do radial line gradient around an image and set the % of it? CSS or SVG or anything can solve the problem

I need to develop the next style:
The gradient around the image has diferents colors and can be uncompleted.
How can I do that and set the % of it?
For people that ask for code:
body {
height: 100vh;
margin: 0;
display: grid;
place-items: center;
background: #222;
}
.module-border-wrap {
max-width: 250px;
padding: 1rem;
position: relative;
background: linear-gradient(to right, red, purple);
padding: 3px;
}
.module {
background: #222;
color: white;
padding: 2rem;
}
I believe you'll need to use SVGs. Here is a gradient you can apply to a path. You can use stroke-dasharray and stroke-offset to get the semi circle as well.
<svg height="150" width="150">
<defs>
<radialGradient id="grad1" cx="80%" cy="20%" r="100%" fx="100%" fy="50%">
<stop offset="0%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(0,200,255);stop-opacity:1" />
</radialGradient>
</defs>
<ellipse cx="100" cy="100" rx="30" ry="30" stroke="url(#grad1)" stroke-width="10" fill="none" stroke-linecap="round" stroke-dasharray="1000" stroke-dashoffset="840"/>
</svg
The stroke-dashoffset="" is the number you can adjust to increase or decrease the size of the circle. This works because you are creating a dashed line, that has very far apart dashes, so it is only showing part of one dash. If you offset that dash you can move it along the path.

Outlined triangle svg animation

I've created a simple outlined triangle. The problem i need to solve - is to create animation of filling the gap between triangles from bottom to top.
When i am using the fill option for polygons, the fill area overlaps the other triangle, so that there is no "hole" in the shape.
body{
background: #7085EA;
}
.triangle-container{
width: 500px;
margin: auto;
text-align:center;
}
.triangle {
stroke: #fff;
fill: transparent;
}
<div class="triangle-container">
<svg height="500" width="500">
<polygon points="250,100 100,400 400,400" class="triangle"/>
<polygon points="250,180 160,360 340,360" class="triangle"/>
</svg>
</div>
Initial codepen is here.
The area that needs to be filled is shown on screenshot here
Any help is appreciated. Thanks in advance!
Based on the advices here, and an another SO issue, came up with the following solution:
body{
background: #7085EA;
}
.triangle-container{
width: 500px;
margin: auto;
text-align:center;
}
.triangle {
stroke: #fff;
}
<div class="triangle-container">
<svg height="500" width="500">
<linearGradient id="loading" x1="0.5" y1="1" x2="0.5" y2="0">
<stop offset="40%" stop-opacity="1" stop-color="#fff">
<animate attributeName="offset" values="0;1;0" repeatCount="indefinite" dur="10s" begin="0s"/>
</stop>
<stop offset="40%" stop-opacity="0" stop-color="#fff">
<animate attributeName="offset" values="0;1;0" repeatCount="indefinite" dur="10s" begin="0s"/>
</stop>
</linearGradient>
<path d="M250,100 L100,400 400,400 250,100 M250,180 L340,360 160,360 250,180z" class="triangle" fill="url(#loading)"></path>
</svg>
</div>

Clip a text using polyline

I want to clip a text such as a heading1 using svg polyline, the idea is to put the H1 behind the polyline background and make it appear like a frosted or blurred, I've done it before but somehow forgot
<svg height="200" width="100%"viewBox="0 0 100 200" preserveAspectRatio="none">
<polyline id="cliptop" points="
8.3,40
16.6,50
24.9,90
33.2,70
41.5,80
49.8,60
58.1,20
66.4,70
74.4,60
83,40
91.3,50
99.6,80
99.6,200
8.3,200
"
style="fill:rgba(255,255,255,0.75);stroke:none;"
/>
<polyline points="
8.3,40
16.6,50
24.9,90
33.2,70
41.5,80
49.8,60
58.1,20
66.4,70
74.4,60
83,40
91.3,50
99.6,80
"
style="fill:none;stroke:rgba(30,0,0,0.8);stroke-width:7;"vector-
effect="non-scaling-stroke"
/>
</svg>
i'd like to use #cliptop as clip-path in css, I tried the clip-path: url(#cliptop). thanks, any advise would be appreciated
This is one ay of doing it. In this case the points are relative to a very small box (a square of 1x1) and `clipPathUnits="objectBoundingBox"``
h1{
padding: 0;
background: silver;
background-size: cover;
height: 50vh;
-webkit-clip-path: url(#clip);
clip-path: url(#clip);
}
<svg height="0" width="0" class="svg-clip" style="position:absolute">
<defs>
<clipPath id="clip" clipPathUnits="objectBoundingBox">
<polyline points="
.083,.4
.166,.50
.249,.90
.332,.70
.415,.80
.498,.60
.581,.20
.664,.70
.744,.60
.83,.40
.913,.50
.996,.80
.996,2.00
.083,2.00
" />
</clipPath>
</defs>
</svg>
<h1></h1>
I've figured it out just like enxaneta replied, here's how it look
<svg height="200" width="100%"viewBox="0 0 100 200"
preserveAspectRatio="none">
<defs>
<filter id="dropshadow" height="100%">
<feGaussianBlur in="SourceAlpha" stdDeviation="1"/>
<feOffset dx="2" dy="2" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.8"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<polyline points="
8.3,40
16.6,50
24.9,90
33.2,70
41.5,80
49.8,60
58.1,20
66.4,70
74.4,60
83,40
91.3,50
99.6,80
"
style="fill:none;stroke:rgba(30,0,0,0.8);stroke-width:3;"vector-effect="non-
scaling-stroke"
/>
</svg>
<h1 class="clipped">70.4%</h1>
<h1 class="clipped2">70.4%</h1>
</div>
<svg height="0" width="0">
<defs>
<clipPath id="clip" clipPathUnits="objectBoundingBox">
<polyline points="
.083,.2
.166,.25
.249,.45
.332,.35
.415,.4
.498,.3
.581,.1
.664,.35
.744,.3
.83,.2
.913,.25
.996,.4
.996,2.00
0,2.00
0,0
" />
</clipPath>
<clipPath id="clip2" clipPathUnits="objectBoundingBox">
<polyline points="
.083,.2
.166,.25
.249,.45
.332,.35
.415,.4
.498,.3
.581,.1
.664,.35
.744,.3
.83,.2
.913,.25
.996,.4
.996,0
0,0
" />
</clipPath>
</defs>
</svg>
and the style
<style>
.framer .clipped,.framer .clipped2{
position: absolute;
top: 0;
margin: 0 auto;
width: 100%;
height: 200px;
line-height: 120px;
font-size: 120px;
letter-spacing: -5px;
text-align: center;
z-index: -2;
}
.framer .clipped{
color: transparent;
text-shadow: 0 0 8px rgba(130,100,100,0.5);
-webkit-clip-path: url(#clip);
clip-path: url(#clip);filter:
}
.framer .clipped2{
-webkit-clip-path: url(#clip2);
clip-path: url(#clip2);
color: #300;
}
</style>

How to set the size of the handle in a QSlider?

I'm trying to add some style to a QSlider I want to use a custom image as the handle that the user drags back and forth. While I've figured out how to use style sheets to have a custom icon drawn where the handle should be, the image is being drawn much too small and I cannot figure out how to make it larger.
Setting width and height seem to do nothing. I've tried using image, border-image and background-image, but none give me the ability to set the size of the handle image. Does anyone know how to do this?
This is the style sheet that I've been adding to my QSlider in QtDesigner:
QSlider::handle:vertical {
image: url(:/data/icons/mixer-slider-handle.svg);
width:64px;
height:64px;
}
This is the SVG:
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="30"
height="45"
viewBox="0 0 7.9374997 11.90625"
version="1.1"
id="svg8"
>
<defs
id="defs2">
<linearGradient
id="linearGradient844"
inkscape:collect="always">
<stop
id="stop840"
offset="0"
style="stop-color:#cecece;stop-opacity:1;" />
<stop
id="stop842"
offset="1"
style="stop-color:#ffffff;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient824">
<stop
style="stop-color:#cecece;stop-opacity:1;"
offset="0"
id="stop820" />
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="1"
id="stop822" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient824"
id="linearGradient826"
x1="-3.9103179"
y1="297.24557"
x2="-3.8304768"
y2="285.38882"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.8683302,0,0,0.96503255,7.3827223,9.9179025)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient844"
id="linearGradient838"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.86322913,0,0,0.81935486,7.5301966,52.317886)"
x1="-3.8119318"
y1="285.99686"
x2="-3.7885454"
y2="296.82458" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-285.09375)">
<rect
style="fill:url(#linearGradient826);fill-opacity:1;stroke:#0e0e0e;stroke-width:0.1373108;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect818"
width="5.157938"
height="11.397007"
x="1.453124"
y="285.36124"
ry="2.866178" />
<rect
style="opacity:1;fill:url(#linearGradient838);fill-opacity:1;stroke:none;stroke-width:0.12615089;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect828"
width="4.6027613"
height="8.9100981"
x="1.7161824"
y="286.60291"
ry="2.184411" />
<path
style="fill:none;stroke:#000000;stroke-width:0.24780074px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 1.8804469,291.0695 4.3266789,0.047"
id="path846"
inkscape:connector-curvature="0" />
</g>
</svg>
Looks like the answer is to set the margin attribute for both the groove and the handle to reflect the size of the handle you are using.
This worked for me:
.QSlider::groove:vertical {
border: 1px solid #111;
background-color: #333;
width: 6px;
margin: 24px 12px;
}
.QSlider::handle:vertical {
image: url(:/data/icons/mixer-slider-handle.svg);
margin: -24px -12px;
height: -30px;
}

Creating a believable elliptical orbiting element (plane) with SVG and CSS?

first time question poster here. After over 2 days of searching on StackOverflow & other sites, and playing on my own with CodePen, I just cannot seem to figure out how to create an orbiting path for an SVG element that isn't a circle.
Here's a copy of the closest thing I've come up with: http://codepen.io/Whatsit2yaa/pen/epbbRR?editors=100
And the code -
HTML:
<svg width="600" height="500" viewbox="0 0 600 500">
<path id="flight-path" fill="none" stroke="#CCC" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="10" d="M592.7,308.1c-28.5,108.8-183,162.6-344.9,120.2C85.8,385.8-22.4,263.2,6.1,154.3
C34.6,45.5,189.1-8.3,351.1,34.2C513,76.6,621.2,199.3,592.7,308.1z"/>
<g id="plane" transform="translate(-199.4, -413.2)" scale="0.8">
<path d="M199.4,413.2L199.4,413.2c0.3,5.4,10.9,8.9,10.9,8.9l29.9,7.5l13.5,41.2l12.1,3.3l-6.6-37.8l24.6,6.8l3.9,6.2
l8,3.5l-4-14.1l10.7-10l-8.6-1.1l-6.5,3.3l-24.6-6.8l25.1-29l-12.1-3.3l-32.8,28.4l-29.7-9C213.1,411.1,202.4,408.7,199.4,413.2z" fill="#333"/>
</g>
<animateMotion
xlink:href="#plane"
dur="3s"
begin="0s"
fill="freeze"
repeatCount="indefinite"
rotate="auto-reverse"
>
<mpath xlink:href="#flight-path" />
</animateMotion>
</svg>
CSS:
html, body {
height: 100%;
}
body {
background: -webkit-linear-gradient(#FFF, #3276b1); /* For Safari 5.1 to 6.0 */
background: -o-linear-gradient(#FFF, #3276b1); /* For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(#FFF, #3276b1); /* For Firefox 3.6 to 15 */
background: linear-gradient(#FFF, #3276b1);
}
svg {
position: fixed;
overflow: visible;
top: 20%;
height: 60%;
left: 20%;
width: 60%;
}
Here's a pen showing what I'm trying to achieve:
http://codepen.io/guerreiro/pen/obhzc
And the code -
HTML:
<svg viewBox="0 0 160 160" width="160" height="160">
<circle cx="80" cy="80" r="50" />
<g transform=" matrix(0.866, -0.5, 0.25, 0.433, 80, 80)">
<path d="M 0,70 A 65,70 0 0,0 65,0 5,5 0 0,1 75,0 75,70 0 0,1 0,70Z" fill="#FFF">
<animateTransform attributeName="transform" type="rotate" from="360 0 0" to="0 0 0" dur="1s" repeatCount="indefinite" />
</path>
</g>
<path d="M 50,0 A 50,50 0 0,0 -50,0Z" transform="matrix(0.866, -0.5, 0.5, 0.866, 80, 80)" />
</svg>
CSS:
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
body {
background: #FC0;
}
svg {
position: fixed;
top: 20%;
height: 60%;
left: 20%;
width: 60%;
}
I can't seem to get an SVG that isn't round to properly adjust & transform as it circles a planet in an ellipse that goes around an orbit.
I'm open to using SVG images with CSS transform if this is beyond SMIL capabilities. Any animators have advice/help for me? Thanks so much!

Resources