non-rectangular shapes with css only? - css

I would like to have logos and text in rectangle shapes with the corners cut off. Do I need to use an SVG or can I do it in pure css?
funky square shape
I know its possible to make circles, triangles, stars etc in with only css but I am having trouble coding this particular shape up. Its a rectangle with the corners cut off.

example from my comment:
div {
/* demo purpose */
margin:0.5em;
height:100px;
width:100px;
display:inline-flex;
align-items:center;
justify-content:center;
/* end demo purpose, use your own display and sizes */
background:
linear-gradient(45deg, transparent 10px, black 10px, black 40%, transparent 40% ),
linear-gradient(225deg, transparent 10px, black 10px, black 40%, transparent 40% ),
linear-gradient(-225deg, transparent 10px, black 10px, black 40%, transparent 40% ),
linear-gradient(-45deg, transparent 10px, black 10px, black 40%, transparent 40% ),
linear-gradient(0deg, transparent 30%, black 30%, black 70%, transparent 70% );
color:lightgray;
position:relative;
font-size:40px;
}
div:after {
content:'';
padding:5px;
border:5px solid black;
position:absolute;
}
/* Now fill up any corner from a class */
div.green:after {
background:lime;
bottom:0;
right:0;
}
div.red:after {
background:tomato;
top:0;
right:0;
}
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.1/css/font-awesome.min.css" rel="stylesheet"/>
<div class="green">
<i class="fa fa-mobile"></i>
</div>
<div class="red">
<i class="fa fa-crosshairs"></i>
</div>

Use ::after and ::before
js fiddle:
https://jsfiddle.net/ymympva0/
.weird-shape:before {
content: "";
position: absolute;
top: 0;
left: 0;
border-bottom: 29px solid black;
border-left: 29px solid white;
border-right: 29px solid white;
width: 42px;
height: 0;
}
.weird-shape:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
border-top: 29px solid black;
border-left: 29px solid white;
width: 42px;
height: 0;
}
I have included 2 shapes. one is a colored version so you can see what it really does.

you will have to add a div with a background the same as the color behind the image and have it cover the corners you want removed.

Related

How to set striped background skipping the first stripe?

I'm trying to build a striped bar using repeating-linear-gradient. I'm getting this:
I need to skip the first strip, so I could have this:
Is there a straightforward way to do that with css?
.stripe {
margin-left: 50px;
width: 275px;
height: 58px;
color: black;
background: repeating-linear-gradient(
to right,
green,
green 5px,
#ccc 5px,
#ccc 51px
);
}
<div class="stripe"></div>

Button with 2 colors as a border

I'm trying to create a button that has two colors as a border.
The two colors i need used are blue: #00a7e1, orange: #f6531d.
I would like to just use css if possible.
Thank in advance!
link to button concept
Example:
.btn
{
border: 0;
padding: 4px;
display: inline-block;
background: linear-gradient(20deg, #00a7e1 49%, #e65300 50%);
}
.bg
{
background: #349645;
padding: 8px 14px;
font: bold 24px Consolas;
}
.btn:active .bg
{
background: #0a1117;
color: #ffffff;
}
<div class="btn"><div class="bg">YOU'R TITLE</div></div>
<button class="btn"><div class="bg">YOU'R TITLE</div></div>
You may also play with gradient and background-clip (see comments in CSS)
button {
vertical-align: top;
border: 5px solid transparent;/* give extra space for gradients colors */
font-size: 2.5rem;
margin: 0.25em;
padding: 0.5em 2em;
background: linear-gradient(#333, #333),/* black turned into gradient to hold with background-clip and hide the 2 color gradient under it */
linear-gradient(/* 2 colors to draw under the borders also via background-clip*/
to bottom left,
rgb(230, 83, 0) 50%,
gray 51%,
rgb(0, 166, 224) 40%
)
no-repeat center center;
background-clip:
padding-box, /* drawn inside including padding area */
border-box;/* drawn also under borders */
background-size:
100% 100%,
110% 150%;/* must be bigger than 100% so it include also borders, else it repeats */
color: white;
box-shadow: 0 0 2px 2px black, inset 0 0 2px black;/* did you want this too ? */
}
<button>BUTTON</button> <button> TO</button> <button> PLAY</button>
If you think this is too much, you also have border-image .
Simply use border-image with a gradient:
button {
padding:20px;
border:5px solid;
border-image:linear-gradient(60deg,#00a7e1 50%,#f6531d 0) 20;
background:transparent;
}
<button>some text</button>

Border-image linear-gradient as two-tone solid color

I have this box with a linear gradient background created as a two tone solid color. One color is 44px - the rest has another color, like this:
background: linear-gradient(to left, #365aa5 44px, #f5f5f5 0);
Works great. Now I would like to add a two-tone border to the top and bottom of this element using border image linear gradients the same way - so that the colors of the border follow the color of the background. The trick is to use linear gradients as solid colors.
I have tried something like this:
border-image: linear-gradient(right, #365aa5 44px, #000 0);
border-style: solid;
border-width: 2px 0 2px 0;
But obviousley, it's not working.
Any ideas how I could make this work?
JsFiddle here.
You need to add a number in the end of the border-image property. In your case it has no effect but it is still required. Also use to right instead of right
div {
height: 50px;
width: 80%;
padding: 4px;
box-sizing: border-box;
position: relative;
background: linear-gradient(to left, #365aa5 44px, #f5f5f5 0);
/* What I'm trying: */
border-image: linear-gradient(to right, #365aa5 44px, #f5f5f5 0) 1;
border-style: solid;
border-width: 2px 0 2px 0;
}
body {
padding: 20px;
background-color: #fff;
}
<div>Two tone solid color top and bottom border to<br> match the two tone background</div>
I took the blue color so it is easier to see.
EDIT: Also possible as vibhu suggested:
border-image: linear-gradient(to right, #365aa5 44px, #f5f5f5 0);
border-image-slice: 1;
You can add the two tone border by using the below additional code::
div::after {
content: "";
position: absolute;
height: 2px;
width: 44px;
right: 0;
background: #365aa5;
top: -2px;
}
div::before {
content: "";
position: absolute;
height: 2px;
width: 44px;
right: 0;
background: #365aa5;
bottom: -2px;}
Jsfiddle added here: https://jsfiddle.net/y2Ln2h86/

Creating a triangle in css with a gradient background

I am trying to create a triangle in css with a gradient background. I have not had any success as yet. Is there way to do this to bring off this effect seen in the image below.
(The triangle that is attached to the Wrong password error box.)
Design in Photoshop
This is the design I have so far in HTML and CSS.
Here is the css I have for the triangle at the moment.
.error-triangle {
wwidth: 0;
height: 0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-right: 10px solid blue;
margin-top: 64px;
margin-left: 350px;
position: fixed;
-webkit-box-shadow: 0 0 3px rgba(102,65,65,.25), 2px 3px 5px rgba(70,34,34,.25), inset 1px 2px rgba(255,255,255,.25);
-moz-box-shadow: 0 0 3px rgba(102,65,65,.25), 2px 3px 5px rgba(70,34,34,.25), inset 1px 2px rgba(255,255,255,.25);
box-shadow: 0 0 3px rgba(102,65,65,.25), 2px 3px 5px rgba(70,34,34,.25), inset 1px 2px rgba(255,255,255,.25);
background-image: -webkit-linear-gradient(bottom, #eb6767, #d94040 35%, #eb6767);
background-image: -moz-linear-gradient(bottom, #eb6767, #d94040 35%, #eb6767);
background-image: -o-linear-gradient(bottom, #eb6767, #d94040 35%, #eb6767);
background-image: -ms-linear-gradient(bottom, #eb6767, #d94040 35%, #eb6767);
background-image: linear-gradient(to top, #eb6767, #d94040 35%, #eb6767);
}
I was using this tutorial on CSS tricks.
Creating triangles (or other shapes - pentagons, hexagons, octagons, decagons, dodecagons, tetradecagons, octadecagons and so on) with a gradient (or any other kind of image background) is really easy with CSS transforms.
But in this case you don't even need a triangle. You just need to rotate a square pseudo-element by 45deg and apply the gradient on that from corner to corner.
demo
<div class='warn'></div>
CSS:
.warn {
position: relative;
margin: 0 auto;
border: solid 1px darkred;
width: 12em; height: 3em;
border-radius: .2em;
background: linear-gradient(lightcoral, firebrick);
}
.warn:before {
position: absolute;
top: 50%; left: 0;
margin: -.35em -.45em;
border-left: inherit; border-bottom: inherit;
/* pick width & height such that
the diagonal of the square is 1em = 1/3 the height of the warn bubble */
width: .7em; height: .7em;
border-radius: 0 0 0 .2em;
transform: rotate(45deg);
background: linear-gradient(-45deg, firebrick -100%, lightcoral 200%);
content: '';
}
You can create a CSS triangle, but not a CSS triangle that is itself a gradient. The only trick I would suggest is to pick a color that most resembles the color within the gradient background. It just depends on how big your gradient actually is, and how well the triangle will blend in.
For the red div, you could try using the color #d94040, but then it will lack a border and a drop shadow. However, these can be added. To add a border to a CSS triangle, you can place a inside your that is also a CSS triangle that is the same size. TThis would require using absolute positioning and z-index to overlap them.
Or you can use ::after or ::before to create your CSS triangles without the added HTML code, but then that would only work in modern browsers only.
In CSS3, you can create a triangle with the 'border trick'. This border can be colored and can have a background.
WebKit now (and Chrome 12 at least) supports gradients as border image.
For a more supported solution i suggest you to 'gradient' the background of a :before pseudo element for witch you would apply a 'background-gradient' + the ( css triangle with border ) trick.
Here is a cssTriangle generator for you to experiment.

Can I add background color only for padding?

I have a header box including border and padding and background color for that box,
can I change the background color only for the padded region after the border and then the same background color for the rest of the width (i.e. grey in the given code)?
Just a pinch of the code where I want the padded background color:
nav {
margin:0px auto;
width:100%;
height:50px;
background-color:grey;
float:left;
padding:10px;
border:2px solid red;
}
I am sorry everyone that this is the solution the true one where you don't have to actually set the padding.
https://jsfiddle.net/techsin/TyXRY/1/
What I have done...
Applied two gradients on background with both having one start and end color. Instead of using solid color. Reason being that you can't have two solid colors for one background.
Then applied different background-clip property to each.
thus making one color extend to content box and other to border, revealing the padding.
Clever if I say so to myself.
div {
padding: 35px;
background-image: linear-gradient(to bottom, rgba(240, 255, 40, 1) 0%, rgba(240, 255, 40, 1) 100%), linear-gradient(to bottom, rgba(240, 40, 40, 1) 0%, rgba(240, 40, 40, 1) 100%);
background-clip: content-box, padding-box;
}
<p>Padding IS COLORED</p>
<div>Mexican’t professor plum charlie chaplin? Facial accessory lorreto del mar Daniel plainview landed gentry circus strongman sam elliott zap rowsdower, lorreto del mar off-piste frightfully nice mustachio landed gentry Daniel plainview zap rowsdower toothbrush
circus strongman boogie nights sam elliott Daniel plainview facial accessory, Daniel plainview man markings boogie nights mr frothy-top sam elliott worn with distinction mustachio zap rowsdower off-piste Daniel plainview toothbrush lorreto del mar frightfully
nice wario facial accessory mr frothy-top landed gentry circus strongman prostate cancer? Rock n roll star gunslinger villain marquess of queensbury en time-warped cabbie off-piste graeme souness en time-warped cabbie, cunning like a fox gunslinger
dodgy uncle clive villain karl marx marquess of queensbury en time-warped cabbie graeme souness rock n roll star off-piste en time-warped cabbie, rock n roll star lemmy dodgy uncle clive graeme souness professor plum en time-warped cabbie villain gunslinger
en time-warped cabbie marquess of queensbury cunning like a fox devilish cad off-piste karl marx. John aldridge basil fawlty landed gentry louis xiii sam elliott brigadier, et sodales cum dick van dyke mouth coiffure louis xiii landed gentry basil fawlty
john aldridge stiff upper lip brigadier crumb catcher sam elliott?</div>
Use the background-clip and box-shadow properties.
1) Set background-clip: content-box - this restricts the background only to the content itself (instead of covering both the padding and border)
2) Add an inner box-shadow with the spread radius set to the same value as the padding.
So say the padding is 10px - set box-shadow: inset 0 0 0 10px lightGreen - which will make only the padding area light green.
Codepen demo
nav {
width: 80%;
height: 50px;
background-color: gray;
float: left;
padding: 10px; /* 10px padding */
border: 2px solid red;
background-clip: content-box; /* <---- */
box-shadow: inset 0 0 0 10px lightGreen; /* <-- 10px spread radius */
}
ul {
list-style: none;
}
li {
display: inline-block;
}
<h2>The light green background color shows the padding of the element</h2>
<nav>
<ul>
<li>Home
</li>
<li>About
</li>
<li>Blog
</li>
</ul>
</nav>
For a thorough tutorial covering this technique see this great css-tricks post
Another option with pure CSS would be something like this:
nav {
margin: 0px auto;
width: 100%;
height: 50px;
background-color: white;
float: left;
padding: 10px;
border: 2px solid red;
position: relative;
z-index: 10;
}
nav:after {
background-color: grey;
content: '';
display: block;
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
z-index: -1;
}
<nav>Some text or anything</nav>
Demo here
You can use background-gradients for that effect. For your example just add the following lines (it is just so much code because you have to use vendor-prefixes):
background-image:
-moz-linear-gradient(top, #000 10px, transparent 10px),
-moz-linear-gradient(bottom, #000 10px, transparent 10px),
-moz-linear-gradient(left, #000 10px, transparent 10px),
-moz-linear-gradient(right, #000 10px, transparent 10px);
background-image:
-o-linear-gradient(top, #000 10px, transparent 10px),
-o-linear-gradient(bottom, #000 10px, transparent 10px),
-o-linear-gradient(left, #000 10px, transparent 10px),
-o-linear-gradient(right, #000 10px, transparent 10px);
background-image:
-webkit-linear-gradient(top, #000 10px, transparent 10px),
-webkit-linear-gradient(bottom, #000 10px, transparent 10px),
-webkit-linear-gradient(left, #000 10px, transparent 10px),
-webkit-linear-gradient(right, #000 10px, transparent 10px);
background-image:
linear-gradient(top, #000 10px, transparent 10px),
linear-gradient(bottom, #000 10px, transparent 10px),
linear-gradient(left, #000 10px, transparent 10px),
linear-gradient(right, #000 10px, transparent 10px);
No need for unecessary markup.
If you just want to have a double border you could use outline and border instead of border and padding.
While you could also use pseudo-elements to achieve the desired effect, I would advise against it. Pseudo-elements are a very mighty tool CSS provides, if you "waste" them on stuff like this, you are probably gonna miss them somewhere else.
I only use pseudo-elements if there is no other way. Not because they are bad, quite the opposite, because I don't want to waste my Joker.
You can't set colour of the padding.
You will have to create a wrapper element with the desired background colour. Add border to this element and set it's padding.
Look here for an example: http://jsbin.com/abanek/1/edit
the answers said all the possible solutions
I have another one with BOX-SHADOW
here it is JSFIDDLE
and the code
nav {
margin:0px auto;
width:100%;
height:50px;
background-color:grey;
float:left;
padding:10px;
border:2px solid red;
box-shadow: 0 0 0 10px blue inset;
}
it also support in IE9, so It's better than gradient solution,
add proper prefixes for more support
IE8 dont support it, what a shame !
in case you don't want to affect the content background, and you have different padding for each direction, use the following:
div {
width: 440px;
padding: 10px 20px 30px 40px;
box-shadow: inset 0 10px 0 0 lightGreen, inset -20px 0 0 0 lightGreen, inset 0 -30px 0 0 lightGreen, inset 40px 0 0 0 lightGreen;
}
<div>The light green background color shows the padding of the element</div>
I'd just wrap the header with another div and play with borders.
<div class="header-border"><div class="header-real">
<p>Foo</p>
</div></div>
CSS:
.header-border { border: 2px solid #000000; }
.header-real { border: 10px solid #003399; background: #cccccc; padding: 10px; }
There is no exact functionality to do this.
Without wrapping another element inside, you could replace the border by a box-shadow and the padding by the border. But remember the box-shadow does not add to the dimensions of the element.
jsfiddle is being really slow, otherwise I'd add an example.
This would be a proper CSS solution which works for IE8/9 as well (IE8 with html5shiv of course): codepen
nav {
margin: 0px auto;
height: 50px;
background-color: gray;
padding: 10px;
border: 2px solid red;
position: relative;
color: white;
z-index: 1;
}
nav:after {
content: '';
background: black;
display: block;
position: absolute;
margin: 10px;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
}
<nav>lorem ipsum dolor sit amet</nav>
Style the <hr> like this to get a solid line.
.line {
height: 10px;
color: black;
margin: 0;
border-style: solid;
background-color: black;
}
<hr class="line">
You can do a div over the padding as follows:
<div id= "paddingOne">
</div>
<div id= "paddingTwo">
</div>
#paddingOne {
width: 100;
length: 100;
background-color: #000000;
margin: 0;
z-index: 2;
}
#paddingTwo {
width: 200;
length: 200;
background-color: #ffffff;
margin: 0;
z-index: 3;
the width, length, background color, margins, and z-index can vary of course, but in order to cover the padding, the z-index must be higher than 0 so that it will lay over the padding. You can fiddle with positioning and such to change its orientation. Hope that helps!
P.S. the divs are html and the #paddingOne and #paddingTwo are css (in case anyone didn't get that:)
Another trick:
Stack two divs one on top of the other, then apply different background-clip for each (bottom with padding-box, top with content-box):
.rect {
width: 100px;
height: 50px;
border: red solid 5px;
padding: 10px;
position: absolute;
}
.bottom {
background: yellow padding-box;
}
.top {
background: pink content-box;
}
<div>
<div class="rect bottom"></div>
<div class="rect top"></div>
</div>
Linke:
The backgound clip property
Stacking divs

Resources