I'm looking to make a bootstrap btn look a little differently with there being a 5 point at the bottom of its base. I know its possible to do shapes this way using the :before and :after tools and transform but I want to put text inside of them which is why I'm having so much trouble. Is it possible to deal directly with the btn class to make this effect happen?
You can use SkewY as shown in the demo below:
div {
height: 100px;
width: 500px;
display: inline-block;
border: 10px solid green;
border-bottom: none;
text-align: center;
line-height: 100px;
position: relative;
color: green;
font-size: 20px;
}
div:before,
div:after {
content: "";
border-bottom: 10px solid green;
position: absolute;
width: calc(50% + 10px);
height: 100%;
top: 0;
}
div:before {
transform: skewY(5deg);
left: -10px;
}
div:after {
transform: skewY(-5deg);
left: 50%;
}
<div>Request a Quote</div>
gradient can be a first chip approach ...
example in situation: http://codepen.io/gc-nomade/pen/wGEyvd
button {
color:green;
display:block;
width:50%;
margin:1em auto;
padding:1.5em 0 2.5em;
border:none;
background:linear-gradient(to left, green, green) top,
linear-gradient(to bottom, green,green) top left,
linear-gradient(to bottom, green,green) top right,
linear-gradient(to bottom left, transparent 45%, green 47%, green 51%, transparent 52%) bottom left,
linear-gradient(to bottom right, transparent 45%, green 47%, green 51%, transparent 52%) bottom right;
background-repeat:no-repeat;
background-size:100% 3px, 3px 70%, 3px 70%,50% 30%, 50% 30%;
}
<button>REQUEST A CODE</button>
Related
I made a multicolor border :
https://codepen.io/Niavl/pen/vpmvmL
body {
background: #333;
}
.my-div {
text-align: center;
position: relative;
line-height: 100px;
background: #fff;
height: 100px;
width: 100%;
}
/*border bottom*/
.my-div:after {
background: linear-gradient(to right, transparent 45%, #87c846 45%, #87c846 60%, #e32b2d 60%, #e32b2d 70%, #ffc846 70%, #ffc846 95%, #847c6c 95%);
position: absolute;
content: '';
height: 20px;
right: 0;
left: 0;
bottom: -20px;
}
<div class="my-div">
hello
</div>
I use for that css linear-gradient.
It works but it is not clean especially on chrome: There is blur between 2 colors.
Any idea to make it cleaner ?
I am trying to achieve this effect in CSS:
This is my code:
#test {position: relative;margin: 100px;}
#test::after {
background-color: maroon;
box-shadow: 0 -50px 10px 7px gray;
height: 45px;
left: -15px;
position: absolute;
top: 40px;
transform: perspective(150px) rotateX(-45deg);
transform-origin: center bottom 0;
width: 60px;
content: "";
}
<div id="test"></div>
but I am not achieving the expected result with the cast shadow. I wonder if its even possible to do this with CSS only?
Fiddle Demo
Maybe something like this? I added another element representing the shadow:
#shadow {
height: 90px;
left: -15px;
position: absolute;
top: 30px;
background: rgba(0, 0, 0, 0);
width: 60px;
transform: perspective(50px) rotateX(25deg);
box-shadow: 0 -106px 20px 17px #808080;
}
https://jsfiddle.net/zcyy09mp/4/
As mentioned in my comment, I would generally recommend the approach used in my fiddle (which is, use another pseudo-element) or the one in Martin's answer (which is, to use an extra element) but as you've mentioned that the other pseudo-element is already used and you are trying to avoid any extra elements, the other approach is to use gradients as background for the parent element. By using the appropriate side-to-side gradients with background-position, background-size, we can not only get the shape but also an effect very similar to the blurred nature of the shadow.
Below is a sample snippet: (the output is also reasonably responsive as you can see by hovering it)
#test {
position: relative;
height: 100px;
width: 100px;
margin: 100px;
background: linear-gradient(to bottom right, transparent 45%, gray 55%), linear-gradient(to bottom left, transparent 45%, gray 55%), linear-gradient(to bottom, transparent, gray), linear-gradient(gray, gray);
background-repeat: no-repeat;
background-size: 30px 95%, 30px 95%, calc(100% - 60px) 8px, calc(100% - 60px) calc(100% - 8px);
background-position: 0% 100%, 100% 100%, 50% 4px, 50% 100%;
}
#test::after {
position: absolute;
content: "";
background-color: maroon;
width: 100%;
height: 45%;
left: 0px;
top: 100%;
transform: perspective(150px) rotateX(-45deg);
transform-origin: center top 0;
}
/* just for demo */
#test {
transition: all 1s;
}
#test:hover {
height: 200px;
width: 200px;
}
<div id="test"></div>
In the below snippet, I have given a different color for each of the gradient just to visually show how it is achieved.
#test {
position: relative;
height: 100px;
width: 100px;
margin: 100px;
background: linear-gradient(to bottom right, transparent 45%, red 55%), linear-gradient(to bottom left, transparent 45%, blue 55%), linear-gradient(to bottom, transparent, green), linear-gradient(rebeccapurple, rebeccapurple);
background-repeat: no-repeat;
background-size: 30px 95%, 30px 95%, calc(100% - 60px) 8px, calc(100% - 60px) calc(100% - 8px);
background-position: 0% 100%, 100% 100%, 50% 4px, 50% 100%;
}
#test::after {
position: absolute;
content: "";
background-color: maroon;
width: 100%;
height: 45%;
left: 0px;
top: 100%;
transform: perspective(150px) rotateX(-45deg);
transform-origin: center top 0;
}
/* just for demo */
#test {
transition: all 1s;
}
#test:hover {
height: 200px;
width: 200px;
}
<div id="test"></div>
According to the W3 spec, "the 'box-shadow' property attaches one or more drop-shadows to the box". The shadow you want to create is not a drop shadow so there is no CSS that would make the shadow in the picture.
The closest you could achieve is pushing the shadow off one edge by using a negative spread radius:
body {
padding-top: 50px;
}
#test {
margin: 0 auto;
background-color: maroon;
box-shadow: 0 -20px 7px -6px black;
height: 45px;
width: 60px;
transform: perspective(150px) rotateX(-45deg);
transform-origin: center bottom 0;
}
<div id="test"></div>
So I have a div, content of which should always be crossed out diagonally.
I've tried few solutions with few elements that had absolute positions but it wasn't good enough, because content and size of the div that should be crossed out can vary, so crossing out should be adaptive as well.
Basically I need to make something like this: http://www.awesomescreenshot.com/0515d31j22
This should work for you.
.strike {
position: relative;
display: inline-block;
}
.strike:before {
content: "";
position: absolute;
height: 1px;
width: 120%;
background: red;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(25deg);
}
<div class="strike">$55.55</div>
<br><br>
<div class="strike">$555.55</div>
<br><br>
<div class="strike">$5555.55</div>
A couple of linear gradients can do this and it will auto-size to the dimensions of the element and no degree notation is required.
div {
width: 25%;
height: 250px;
margin: 1em auto;
border:1px solid grey;
position: relative;
}
div:after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top:0;
left: 0;
background:
linear-gradient(to bottom left, transparent 0%, transparent 50%, red 51%, transparent 51%, transparent 100%),
linear-gradient(to bottom right, transparent 0%, transparent 50%, red 51%, transparent 51%, transparent 100%);
}
<div></div>
How can I create border corner spacing with CSS like the picture below? The height of the content is not fixed.
You can't do it using just border but you can achieve this using after and box-shadows
see more about after and box-shadow
div {
width: 200px;
height: 100px;
background: #BB67E0;
position: relative;
margin: 50px;
text-align: center;
line-height: 100px;
font-size:30px;
color:#fff;
}
div:after {
position: absolute;
content: "";
width: 2px;
height: 80px;
background: black;
left: -10px;
top: 10px;
box-shadow: 220px 0 0 0 black;
}
div:before {
position: absolute;
content: "";
height: 2px;
width: 180px;
background: black;
left: 10px;
top: -10px;
box-shadow: 0 120px 0 0 black;
}
<div>content div</div>
If you want to use relative height you will have to remove the bottom border or you can use jquery to change the position of the box-shadow
Note:I have given contenteditable to the div so as to see the change when more content is added
div {
width: 200px;
min-height: 100px;
background: #BB67E0;
position: relative;
margin: 50px;
text-align: center;
line-height: 100px;
font-size:30px;
color:#fff;
}
div:after {
position: absolute;
content: "";
width: 2px;
height: 90%;
background: black;
left: -10px;
top: 5%;
box-shadow: 220px 0 0 0 black;
}
div:before {
position: absolute;
content: "";
height: 2px;
width: 90%;
background: black;
left: 10px;
top: -10px;
}
<div contenteditable="true">content div</div>
Edit: This can change the width and height according to your need i got the idea Idea from misterMansam's wonderful answer
div {
width: 200px;
min-height: 100px;
background: #BB67E0;
position: relative;
margin: 50px;
text-align: center;
line-height: 100px;
font-size:30px;
font-size:30px;
color:#fff;
color:#fff;
}
div:after {
position: absolute;
content: "";
width: 90%;
left:5%;
top:0;
height:110%;
top:-5%;
border-top:2px solid black;
border-bottom:2px solid black;
}
div:before {
position: absolute;
content: "";
width: 110%;
left:-5%;
top:0%;
height:100%;
border-left:2px solid black;
border-right:2px solid black;
}
<div contenteditable="true">Content</div>
Using border-image:
We can make use of the border-image to assign a linear-gradient as the border image on all the four sides. We would need a pseudo-element (overlapping the parent container) because the gradient can go only in one direction. Gradients can support percentage based values and hence can adapt to different container dimensions. This can be verified by hovering on the div in the snippet.
The main drawback of this approach is that the border-image property has low browser support. But it is pretty useful when only IE11+ need to be supported because unlike box-shadow it doesn't require fixed dimensions, is not as complex as clip-path and also leaves a spare pseudo-element for other potential usage.
.border-spacing{
position: relative;
height: 100px;
width: 300px;
padding: 10px;
background: rgb(187, 103, 224);
background-clip: content-box;
border-image: linear-gradient(to bottom, transparent 25%, black 15%, black 75%, transparent 75%);
border-image-slice: 4;
border-image-width: 4px;
border-image-repeat: round;
/* Just for demo */
text-align: center;
line-height: 100px;
color: white;
}
.border-spacing:after{
position: absolute;
content: '';
top: -2px; /* half of border-image-slice */
left: -2px; /* half of border-image-slice */
height: calc(100% - 20px); /* 100% - 2 * padding */
width: calc(100% - 20px); /* 100% - 2 * padding */
padding: 10px;
border-image: linear-gradient(to right, transparent 25%, black 15%, black 75%, transparent 75%);
border-image-slice: 4;
border-image-width: 4px;
border-image-repeat: round;
}
/* Just for demo */
.border-spacing{
transition: all 1s;
}
.border-spacing:hover{
height: 150px;
width: 450px;
line-height: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="border-spacing">Content div</div>
Using background-image:
We can make use of the background-image to assign a linear-gradient as the border image on all four sides. We would need a pseudo-element (overlapping the parent container) because the gradient can go only in one direction. Gradients can support percentage based values and hence can adapt to different container dimensions. This can be verified by hovering on the div in the snippet.
Drawback of this approach is also very similar to the previous one in the sense the linear-gradient is only supported by IE10+. Advantages are same as mentioned for the earlier one.
.border-spacing{
position: relative;
height: 100px;
width: 300px;
padding: 10px;
background-image: linear-gradient(to bottom, transparent 25%, black 15%, black 75%, transparent 75%), linear-gradient(to bottom, transparent 25%, black 15%, black 75%, transparent 75%), linear-gradient(to right, transparent 25%, black 15%, black 75%, transparent 75%), linear-gradient(to right, transparent 25%, black 15%, black 75%, transparent 75%);
background-size: 4px 100%, 4px 100%, 100% 4px, 100% 4px;
background-position: 0px 0px, 100% 0px, 0px 0px, 0px 100%;
background-repeat: no-repeat;
/* Just for demo */
text-align: center;
line-height: 100px;
color: white;
}
.border-spacing:after{
position: absolute;
content: '';
top: 10px;
left: 10px;
height: calc(100% - 20px);
width: calc(100% - 20px);
z-index: -1;
background: rgb(187, 103, 224);
}
/* Just for demo */
.border-spacing{
transition: all 1s;
}
.border-spacing:hover{
height: 150px;
width: 450px;
line-height: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="border-spacing">Content div</div>
I admit this approach is insane but - as an experiment - if you support only modern browser and you play a bit(*) using clip-path property (used to cut off the corners) you could try this:
http://codepen.io/anon/pen/qOBzJO
div {
width: 300px;
padding: 10px;
margin: 50px;
background: violet;
background-clip: content-box;
border: 3px #000 solid;
clip-path: polygon(0 20%, 10px 20%, 10px 10px, 15% 10px, 15% 0,
85% 0, 85% 10px, calc(100% - 10px) 10px, calc(100% - 10px) 20%, 100% 20%,
100% 80%, calc(100% - 10px) 80%, calc(100% - 10px) calc(100% - 10px),
85% calc(100% - 10px), 85% 100%, 15% 100%, 15% calc(100% - 10px),
10px calc(100% - 10px), 10px 85%, 0 85%);
-webkit-clip-path: polygon(0 20%, 10px 20%, 10px 10px, 15% 10px, 15% 0, 85% 0,
85% 10px, -webkit-calc(100% - 10px) 10px, -webkit-calc(100% - 10px) 20%,
100% 20%, 100% 80%, -webkit-calc(100% - 10px) 80%,
-webkit-calc(100% - 10px) -webkit-calc(100% - 10px),
85% -webkit-calc(100% - 10px), 85% 100%, 15% 100%, 15%
-webkit-calc(100% - 10px), 10px -webkit-calc(100% - 10px), 10px 85%, 0 85%);
}
Some values are in percentage, that's why vertical lines are shorter in the taller div (this can be solved using fixed values anyway), but as you can see height is not involved in the solution. Another benefit of this approach is the responsiveness (try to stretch the codepen output panel)
(*): I lied. it's not really only "a bit" :)
Flexible on all four sides
The :before pseudo element creates the left and right border
The :after pseudo element creates the top and bottom border
The spacing of the borders is controlled with top, right, bottom, and left (having both a left and right property stretches the element between them, same as the top and bottom)
The borders will always remain the designated offset distance.
Here is a good way to visualise how the pseudo elements are layed out:
Example
div {
background: purple;
height: 50vh;
width: 50vw;
margin: 50px auto;
position: relative;
min-height: 200px;
min-width: 200px;
}
div:before,
div:after {
content: '';
position: absolute;
top: 60px;
left: -20px;
right: -20px;
bottom: 60px;
border: solid 4px #000;
}
div:before {
border-top: none;
border-bottom: none;
}
div:after {
top: -20px;
left: 60px;
right: 60px;
bottom: -20px;
border-left: none;
border-right: none;
}
<div></div>
Single corner space
Sorry for digging but I've made my own interpretation of #misterManSam solution: I wanted to reach the free space in one corner to place the icon on it in my project.
div {
background: purple;
height: 200px;
width: 200px;
margin: 50px auto;
position: relative;
min-height: 200px; /* Just adjust as you wish */
min-width: 200px; /* Just adjust as you wish */
}
div:before { /* Bottom half Borders */
content: '';
position: absolute;
top: 60px; /* Height of left border */
/* Higher value - smaller border line */
left: -20px; /* Margin between div edge */
right: -20px; /* Margin between div edge */
bottom: -20px; /* Margin between div edge */
border: solid 3px #000;
border-top: none;
}
div:after { /* Top half Borders */
content: '';
position: absolute;
top: -20px; /* Margin between div edge */
left: 60px; /* Height of top border */
/* Higher value - smaller border line */
right: -20px; /* Margin between div edge */
bottom: 60px;
border: solid 3px #000;
border-left: none;
border-bottom: none;
}
HTML
<div></div>
Pure HTML + CSS.
https://codepen.io/nigtellios/pen/LYZevGv
Here's an image I'd like to recreate with HTML/CSS:
The center gradient is easy enough, as are the two rings (a border around the center, and a div around that div that has its own border). The outside shadow on the left seems simple enough as well.
Here's my best approximation so far (with a matching fiddle):
<div id="youedge">
<div id="youlight" class="round border radialgradientbg">
</div>
</div>
#youedge {
border:30px solid #888;
border-radius:190px;
width:190px;height:190px;margin:50px;
box-shadow:-30px 0 0 #555;
}
#youlight { width:150px; height:150px; background-color:#2b0c0f; }
.round { border-radius:190px; }
.border { border:20px solid #777; }
body { background-color:#999; }
.radialgradientbg {
background: -moz-radial-gradient(center, ellipse cover, #4c1113 0%, #16040a 100%); /* FF3.6+ */
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#4c1113), color-stop(100%,#16040a)); /* Chrome,Safari4+ */
background: -webkit-radial-gradient(center, ellipse cover, #4c1113 0%,#16040a 100%); /* Chrome10+,Safari5.1+ */
}
What I can't figure out is the 3D lighting effects on the two gray borders around the center. Is there a way to accomplish this in CSS?
You could do it with a single element and using :before and :after along with linear-gradient and box-shadow..
The idea is to put two circles behind the main element with opposite linear gradient backgrounds..
.circle-3d {
position: relative;
width: 150px;
height: 150px;
background: black;
border-radius: 50%;
margin:2em;
}
.circle-3d:before {
position: absolute;
content: '';
left: -20px;
top: -20px;
bottom: -20px;
right: -20px;
background: linear-gradient(90deg, #666, #ccc);
border-radius: 50%;
z-index: -2;
box-shadow: -20px 0 10px -5px #000;
}
.circle-3d:after {
position: absolute;
left: -10px;
top: -10px;
bottom: -10px;
right: -10px;
background: linear-gradient(270deg, #222, #eee);
content: '';
border-radius: 50%;
z-index: -1;
}
<div class="circle-3d"></div>