How to draw a trapezium/trapezoid with css3? - html

When you go to the page http://m.google.com using Mobile Safari, you will see the beautiful bar on the top of the page.
I wanna draw some trapeziums (US: trapezoids) like that, but I don't know how. Should I use css3 3d transform? If you have a good method to achieve it please tell me.

As this is quite old now, I feel it could use with some new updated answers with some new technologies.
CSS Transform Perspective
.trapezoid {
width: 200px;
height: 200px;
background: red;
transform: perspective(10px) rotateX(1deg);
margin: 50px;
}
<div class="trapezoid"></div>
SVG
<svg viewBox="0 0 20 20" width="20%">
<path d="M3,0 L17,0 L20,20 L0,20z" fill="red" />
</svg>
Canvas
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.moveTo(30, 0);
ctx.lineTo(170, 0);
ctx.lineTo(200, 200);
ctx.lineTo(0, 200);
ctx.fillStyle = "#FF0000";
ctx.fill();
<canvas id="myCanvas" width="200" height="200"></canvas>

You can use some CSS like this:
#trapezoid {
border-bottom: 100px solid red;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
height: 0;
width: 100px;
}
<div id="trapezoid"></div>
It is really cool to make all this shapes, Take a look to more nice shapes at:
http://css-tricks.com/examples/ShapesOfCSS/
EDIT:
This css is applied to a DIV element

Simple way
To draw any shape, you can use the CSS clip-path property like below.
You can use free online editors to generate this code (ex: https://bennettfeely.com/clippy/)
.trapezoid {
clip-path: polygon(0 0, 100% 0, 84% 41%, 16% 41%);
}
With reusable code
If you want it more adaptative, you can define a Sass mixin like :
#mixin trapezoid ($top-width, $bottom-width, $height) {
$width: max($top-width, $bottom-width);
$half-width-diff: abs($top-width - $bottom-width) / 2;
$top-left-x: 0;
$top-right-x: 0;
$bottom-left-x: 0;
$bottom-right-x: 0;
#if ($top-width > $bottom-width) {
$top-left-x: 0;
$top-right-x: $top-width;
$bottom-left-x: $half-width-diff;
$bottom-right-x: $top-width - $half-width-diff;
} #else {
$top-left-x: $half-width-diff;
$top-right-x: $bottom-width - $half-width-diff;
$bottom-left-x: 0;
$bottom-right-x: $bottom-width;
}
clip-path: polygon($top-left-x 0, $top-right-x 0, $bottom-right-x $height, $bottom-left-x $height);
width: $width;
height: $height;
}
And then use it for the desired element like this (here parameters are $top-width, $bottom-width, $height) :
.my-div {
#include trapezoid(8rem, 6rem, 2rem);
}

This is an old question... but I want to add a method that has not been mentioned. It is possible to draw triangles with gradients of half color half transparent, and then it is possible to build a trapezoid from 3 gradient shapes. Here is an example code, the 3 blocks drawed in different colors for better understanding:
#example {
width: 250px;
height: 100px;
background-image:
linear-gradient(to top left, red 0 50%, transparent 50% 100%),
linear-gradient(to top right, green 0 50%, transparent 50% 100%),
linear-gradient(blue 0 100%);
background-size:
20% 100%, 20% 100%, 60% 100%;
background-position:
left top, right top, center top;
background-repeat: no-repeat;
}
<div id="example"></div>

You have a few options available to you. You can just plain use an image, draw something with svg or distort a regular div with css transforms. An image would be easiest, and would work across all browsers. Drawing in svg is a bit more complex and is not guaranteed to work across the board.
Using css transforms on the other hand would mean you'd have to have your shape divs in the background, then layer the actual text over them in another element to that the text isn't skewed as well. Again, browser support isn't guaranteed.

Related

CSS gradients and opacity

Below is some css that is used to create a radial gradient pattern.
My question: Is it possible to add opacity to the colors giving them a ghost like effect? Can one use RGBa instead of Purple??
I tried the above but couldn't get it to work as expected
/* Note the RADIAL */
background: repeating-radial-gradient(
circle,
purple,
purple 10px,
#4b026f 10px,
#4b026f 20px
);
Many thanks,
P
You can use RGBa values within repeating radial gradients but you need to make sure that both the start point and end point are set.
Try changing the background colour in .bg and see the gradient colours change.
.bg {
background: red;
height: 500px;
width: 500px;
}
.gradient {
width: 500px;
height: 500px;
background: repeating-radial-gradient(circle, rgba(128,0,128, 0.5), rgba(128,0,128, 0.5) 10px, rgba(75, 2, 111, 0.5) 10px, rgba(75, 2, 111, 0.5) 20px);
}
<div class="bg">
<div class="gradient"></div>
</div>
The following lines can also be used to enable opacity for a div. You can use it in most cases.
.div_element{
opacity : 0.9; /*Value can be changed to increase or decrease opacity level*/
filter : alpha(opacity=90);
}

Tint partially transparent image/background

How can I tint a background image that has transparent sections?
I have tried using background-blend-mode: multiply with background-image and background-color. It works great for opaque images, but does not take the transparency into account, leaving a colored square around the image.
I am using svg images, and could switch to using <img> instead of backgrounds if necessary.
Example:
Left side is my goal, right side is what I get with background-blend-mode: multiply. The base image is a light gray circle, and I multiplied it with red.
Edit: I created a codepen to better illustrate my problem and what I have tried. http://codepen.io/anon/pen/QbbbpZ It has both the original image and my goal (made in Photoshop) on top, with examples of what I have tried below.
Edit2: I'm beginning to wonder if it is even possible to do this with plain HTML/CSS. Would using something like canvas, maybe with shaders, be more appropriate? Is there a library out there for it?
In webkit (Safari, Chrome and Opera) you can use -webkit-mask-image to do the effect.
html:
<div id="blend-mask" class="uiElement uiBG"></div>
css:
#blend-mask {
-webkit-mask-image: url("http://i.imgur.com/JLjAor5.png");
background-color: #f00;
background-blend-mode: multiply;
}
#goal {
background-image: url("http://i.imgur.com/JLjAor5.png");
}
#pageBG {
width: 400px;
height: 400px;
background-image: url("http://lorempixel.com/g/400/200/");
background-color: rgba(255,0,0,0.25);
background-blend-mode: multiply;
color: white;
text-shadow: 0 0 0.25em black;
}
.uiElement {
width: 100px;
height: 100px;
margin: 25px;
display: inline-block;
}
.uiBG {
background-size: contain;
background-repeat: no-repeat;
background-image: url("http://i.imgur.com/rkRJbzH.png");
}
Example working:
http://codepen.io/anon/pen/vONVry
if you want to make it work as well in firefox check this post maybe will help:
Is there a -moz-mask CSS property, like -webkit-mask-image?
As well you can check using canvas to tint, there is this post that maybe can help:
http://www.playmycode.com/blog/2011/06/realtime-image-tinting-on-html5-canvas/

How would I create a radial gradient in my border?

I'm trying to accomplish the following:
Basically, this is just a block element:
<div></div>
div {
width: 100px;
height: 100px;
}
How would I put the radial gradient image inside the top left of the elements border?
You can use border-image with some radial-gradient like this:
HTML:
<div><div>
CSS:
div {
width:200px;
height:200px;
background:blue;
border-style:solid;
border-image:-webkit-radial-gradient(-15% -15%, farthest-side, red, blue) 20/8;
border-image:-moz-radial-gradient(-15% -15%, farthest-side, red, blue) 20/8; //Will work starting with FF29.
border-image:radial-gradient(-15% -15%, farthest-side, red, blue) 20/8;
}
Here is the Fiddle
NOTE: Unfortunately Internet Explorer does not support this yet. The current version of Firefox (29.0.1) does have support, but all previous versions including ESRs won't render it correctly, and there is nothing on the horizon for IE, and all past versions will never support this method. If you need to support any versions of IE, you'll need to use another method, such as using a pseudo-element :before.
http://jsfiddle.net/ypJ8k/2/
<div class="div1">
<div class="div2"></div>
</div>
You can do it without pseudo elements like after so your gradiant will be much more accurate
the big wall of css is just the gradiant. go to http://www.colorzilla.com/gradient-editor/, paste that gradiant (you have space before and after so you can copy it nicely from the fiddle) and modifie it at will
updated: bigger size (300x300). http://jsfiddle.net/ypJ8k/3/
One pseudo element should be enough with a radial gradient background from the corner and appropriate color stop.
Codepen Demo
CSS
.element {
width:100px;
height:100px;
margin:50px auto;
position: relative;
background-color: lightblue;
}
.element:before {
content:"";
position: absolute;
width:120%;
height:120%;
top:-20%;
left:-20%;
background: -webkit-radial-gradient(top left,red ,lightblue 50%, lightblue);
background: -moz-radial-gradient(top left,red ,lightblue 50%, lightblue);
background: radial-gradient(top left,red ,lightblue 50%, lightblue);
z-index: -1;
}

Diagonal line through <div> or <span>

I'm wanting to have a diagonal line drawn from the upper-right corner of a <div> or <span> to the lower-left corner. The problem is that the content will sometimes be longer or shorter. So, something like a static image won't work. Basically I want what's described here (How to create a diagonal line within a table cell?) but for a <div> or a <span>.
This has some interesting ideas: http://jsfiddle.net/zw3Ve/11/
So does this: http://css-tricks.com/forums/discussion/13384/diagonal-line/p1
This is kind of a retry at this post: How to strike through obliquely with css
I can't seem to figure any of this out though. It seems like a pure CSS solution should work here, but I just don't have the skills to make that happen. jQuery is an option for me as well.
You can do this with an inline SVG background, using only CSS and no javascript.
.background {
// Draw an SVG top left to bottom right
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 10 10'> <path d='M0 0 L0 10 L10 10' fill='red' /></svg>");
background-repeat:no-repeat;
background-position:center center;
//scale it
background-size: 100% 100%, auto;
}
See my fiddle:
http://jsfiddle.net/3GWw2/
Is first fiddle as example with image in background instead not good enough?
http://jsfiddle.net/zw3Ve/410/
.line {
display:inline-block;
border: 1px solid #ccc;
margin: 10px;
padding: 10px;
background:url(http://i.piccy.info/i7/c7a432fe0beb98a3a66f5b423b430423/1-5-1789/1066503/lol.png);
background-size:100% 100%;
}
You can do this with linear-gradient. For example if I want a green and white square that cuts diagonally from bottom left to top right, I give it this background attribute:
background: linear-gradient(to bottom right, white, white 50%, green 50%, green);
This means that it starts as white at the top left corner and continues as white all the way to the diagonal line. The transition is immediately from white to green with no actual gradient as both are set at 50%. If you want a gray line between, you could try this:
background: linear-gradient(to bottom right, white, white 48%, gray 48%, gray 52%, green 52%, green);
You might use an SVG image like this one:
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
<svg version="1.1" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="200px" height="50px" viewBox="0 0 200 50">
<line fill="none" stroke="#000" x1="0" y1="0" x2="200" y2="50"/>
</svg>
Set it as background of your span or div
.class-of-div-or-span { background: url("line.svg") no-repeat scroll 0 0 / 100% 100% transparent; }
Note: you have to give your span display:block or display:inline-block in order to work.
You could also inline the svg, use it in an object tag or embed it in your css.
Actually this is more of a question about geometry than coding. With squares this is easy, but with rectangles you'll have to do the math yourself. Remember those kids complaining that they'll never have to calculate a diagonal's length in "real life"? :P
Here's what I did:
div.container /*makes a square container (300x300)*/
{
width: 300px;
height: 150px;
background-color: #aaa;
padding-top: 150px;
}
div.line
{
position: relative;
z-index: 1;
left: -61px; /*this is something I don't understand but apparently is required*/
width: 423px; /*since container is a square this equals to its diagonal: 300*1.41*/
height: 1px;
background-color: #000;
transform: rotate(45deg); /*again, this is easy since its a square. In rectangle you'll have to find a tangent*/
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
}
HTML:
<div class="container">
<div class="line"></div>
</div>
and a jsfiddle: http://jsfiddle.net/LWAKn/

using css, how to create a white circle within a transparent div?

I wish to create a white circle with fuzzy edges contained within a transparent div by using css gradients.
With the z-index higher than the body and absolute positioning I should be able to move this over any part of the page and "white-out" everything beneath the circle.
I have tried my favorite gradient generators, but they haven't worked.
<div id="circle"></div>
css
#circle {
width: 50px;
height: 50px;
-webkit-border-radius: 25px;
-moz-border-radius: 25px;
border-radius: 25px;
}
Try using http://www.colorzilla.com/gradient-editor/.
Here's one I made using their tool: (Set the orientation to radial)
http://www.colorzilla.com/gradient-editor/#ffffff+24,ffffff+59&1+31,0+34;Custom
To make the edges more fuzzy, drag the second opacity stop further from the white - and vice versa.
try white background with box-shadow's inset property to create fuzzy edges. Although I don't get what fuzzy means to you. If you have a specific color in mind for the edges, I might be able to give you the code.
Used the gradient suggested by George Reith.
CSS
#white-circle {
background: radial-gradient(ellipse at center center , #FFFFFF 24%, #FFFFFF 31%, rgba(255, 255, 255, 0) 34%, rgba(255, 255, 255, 0) 71%) repeat scroll 0 0 transparent;
height: 100px;
left: 150px;
position: absolute;
top: 0;
width: 100px;
z-index: 1;
}
Here is the outcome: http://jsbin.com/avipih/1
I guess that radial gradient is an overkill for such purpose. Here's much simplier solution with better browser support: http://cdpn.io/yrJji