CSS Styling Left and bottom border with angled tip - css

I'm trying to get some angle on the tip of a left and bottom border on a div or image. Can't seem to replicate this kind of style Desired Output
This is what I have come up so far. When using borders angle tips are pointing outwards though
Using box shadow
<div class="container">Text Content or Image</div>
.container {
background-color: blue;
padding: 100px;
box-shadow: -10px 20px 0px 5px #f71e1e;
}
Using border
.container {
background-color: blue;
padding: 100px;
border-bottom: 15px solid #f71e1e;
border-top: 15px solid white;
border-left: 15px solid #f71e1e;
border-right: 15px solid white;
}
https://jsfiddle.net/su8we1vq/

One approach is as follows, which does allow for easy changes to be made via CSS custom properties; the code is below with explanatory comments in the code:
/* CSS custom properties to handle the border's
color and size: */
:root {
--borderColor: #f00;
--borderSize: 10px;
}
/* simple reset to remove default margins and padding,
and also forcing browsers to use the same basis for
calculating element sizes: */
*,
::before,
::after {
/* includes any assigned padding and border-widths
in the declared size of the element: */
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container {
background-color: blue;
/* for no reason other than easily placing the contents of
the element to the vertical center and left (inline-start): */
display: grid;
place-content: center start;
block-size: 20vh;
/* allows for responsive sizing, the preferred size is 80vw
(80% of the viewport width), but with a minimum size of
20rem and a maximum size of 1200px: */
inline-size: clamp(20rem, 80vw, 1200px);
/* in romantic languages, derivatives of Italian (English,
German...) this is the top/bottom margin; we're using
logical properties in order that other languages might be
laid out appropriately for their own languages' inline and
block axes): */
margin-block: 20vh;
/* in romantic languages (as above) this is equivalent to
left/right margin: */
margin-inline: auto;
/* as above, but here we set padding on the inline-axis (left/right
in romantic languages and derivatives): */
padding-inline: 1em;
/* to allow absolute positioning for pseudo-elements: */
position: relative;
}
.container::before,
.container::after {
content: '';
background-color: var(--borderColor);
position: absolute;
transform-origin: right top;
}
.container::before {
/* taking the full size of the block axis of the parent: */
block-size: 100%;
/* sizing the inline axis to the desired size of the "border" */
inline-size: var(--borderSize);
top: 0;
right: 100%;
/* skewing the normal quadrilateral shape of an HTML element: */
transform: skewY(-45deg);
}
.container::after {
/* the size of the desired "border": */
block-size: var(--borderSize);
/* the full inline size of the parent: */
inline-size: 100%;
top: 100%;
left: 0;
transform: skewX(-45deg);
}
<!-- the original HTML: -->
<div class="container">Text Content or Image</div>
<!-- a second element, demonstrating the possible "theming": -->
<div class="container"
style="--borderColor: lightskyblue;
--borderSize: 2em;
background-color: palegreen;">Text Content or Image</div>
JS Fiddle.
It's worth noting though that there is a slight problem with this approach, where the two pseudo-elements meet, on the lower-left, there is a visible sliver of the background-color of whatever is behind the element.

The easiest way to achieve this would be by using multiple box-shadow, like this:
.container {
background-color: blue;
padding: 100px;
box-shadow: -1px 1px 0px #f71e1e,
-2px 2px 0px #f71e1e,
-3px 3px 0px #f71e1e,
-4px 4px 0px #f71e1e,
-5px 5px 0px #f71e1e,
-6px 6px 0px #f71e1e,
-7px 7px 0px #f71e1e,
-9px 9px 0px #f71e1e,
-10px 10px 0px #f71e1e;
}
Yeah, it doesn't look pretty syntax-wise but hey :(

clip-path with border can do it. I added a CSS variable to easily control the size of the shadow
.box {
--s: 10px; /* control the size of the shadow */
background-color: blue;
margin: 50px;
height: 100px;
border: solid #f71e1e; /* the color here */
border-width: 0 0 var(--s) var(--s);
clip-path: polygon(0 var(--s),var(--s) 0, 100% 0,100% 100%,100% calc(100% - var(--s)),calc(100% - var(--s)) 100%,0 100%);
}
<div class="box"></div>
Also with multiple background to have less code:
.box {
--s: 10px; /* control the size of the shadow */
margin: 50px;
height: 100px;
background:
linear-gradient(blue 0 0) calc(100% + var(--s)) calc(-1*var(--s)) no-repeat,
#f71e1e;
clip-path: polygon(0 var(--s),var(--s) 0, 100% 0,100% 100%,100% calc(100% - var(--s)),calc(100% - var(--s)) 100%,0 100%);
}
<div class="box"></div>

Related

How do I use gradient image which gradates in both directions as border-image?

I want my <div> to have a bottom border which starts from a distance away from the left. It's like:
abc
^^^^^^^^^^
where ^ stands for a piece of border.
I achieved this using border-image. I set a border-image to a linear-gradient() image, which starts transparent, and becomes gray from some pixels.
<style>
div {
width: 200px;
border-top-style: none;
border-bottom-style: solid;
border-width: 1px;
border-image: linear-gradient(to right,
transparent 0,
transparent 1em,
lightgray 1em,
lightgray 100%) 100% 1;
}
</style>
<div>abc</div>
Now the new requirement is to add a 1px white line right below the existing line to mimic a 3d effect. I thought I could simply add a vertical gradient to the border image, but I don't know how to do it.
Instead of border consider multiple background. I used different colors to better see the result:
.box {
width: 200px;
background:
linear-gradient(blue, blue) 1em 100%/ 100% 1px no-repeat,
linear-gradient(red, red) 1em 100%/ 100% 2px no-repeat;
}
<div class="box">abc</div>
You can Achive it with box-shadow
If you are using display: flex to your div you should position pseudo after element using position: absoute
See this example:
body {
background-color: lightgreen;
}
div {
display: flex;
position: relative;
}
div:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
display: block;
width: 200px;
height: 1px;
box-shadow: 10px 1px 0 0 lightgray, 10px 2px 0 0 white;
}
<div>abc</div>
<div>edf</div>

3D Box Shadow effect

So I know how to do a basic box shadow with CSS3. You can see that in the top of the graphic below.
The effect I'm trying to achieve is a 3D box shadow, as shown in the bottom of the graphic below.
Any ideas on how to do this with CSS3 box shadows?
Unfortunately box shadows are effectively just flat layers. However you can apply multiple box shadows to create this effect.
.box-shadow-3d{
box-shadow: 1px 1px 0px #999,
2px 2px 0px #999,
3px 3px 0px #999,
4px 4px 0px #999,
5px 5px 0px #999,
6px 6px 0px #999;
}
you can use pseudo element for as shadow
div {
background: black;
height: 100px;
width: 100px;
position: relative;
}
div:after,
div:before {
content: '';
background: grey;
position: absolute;
}
div:after {
width: 100%;
height: 20px;
left: 10px;
bottom: 0;
transform: translatey(100%) skewx(45deg);
}
div:before {
width: 20px;
height: 100%;
right: 0;
transform: translatex(100%) skewy(45deg);
top: 10px;
}
<div></div>
Here is a real 3D shadow using perspective and pseudo-element :before.
body {
background: lightblue;
}
.foo {
position: relative;
display: inline-block;
-webkit-perspective: 1000px;
-moz-perspective: 1000px;
persepctive: 1000px;
margin: 20px;
margin-top: 50px;
}
.foo .box {
transform: rotateY(-40deg);
height: 350px;
width: 250px;
background-color: black;
}
.foo:before {
content: "";
top: -15px;
position: absolute;
width: 50px;
height: 375px;
background-color: grey;
transform: translateX(215px) translateY(2.7px) rotateY(55deg)
}
<div class="foo">
<div class="box"></div>
</div>
You can stack the horizontal/vertical offsets of several box-shadows, each slightly bigger than the previous one. The more shadows you add, the more pronounced the effect. Here is a fiddle example.
div {
background: black;
height: 100px;
width: 100px;
box-shadow: 0 01px gray,
01px 0 gray,
01px 02px gray,
02px 01px gray,
02px 03px gray,
03px 02px gray,
03px 04px gray,
04px 03px gray,
04px 05px gray,
05px 04px gray,
05px 06px gray,
06px 05px gray;
}
I had some problems with these two options, so I adapted some diagonal gradients from Lea Verou's excellent book CSS Secrets. I thought about creating a gradient inside a right and bottom border via border-image, but that property does not allow edge targeting, à la border-right-image, etc.
So, I settled on using a pseudo element with two truncated corners, which seems to work pretty well. You have to be careful to adjust the width of the gradient to be 1.414 the size of half the padding, since this would be the diagonal of a square (square root of two). Also, since that's a pseudo element, be careful of the right placement. Interested to hear what you folks think.
div {
background: #bbb;
padding: 1em 1.2em;
width: 50%;
margin: 0 auto;
color: #111;
font: 150%/1.2 Georgia, Palatino, Times, serif;
position: relative;
}
div:after {
content:" ";
position:absolute;
top:0;
left: 0;
width:100%;
height:100%;
padding: 1.42em; /* (square root of gradient position) */
background: #000; /* Fallback if not supported */
background: linear-gradient(-135deg, transparent 2em, #000 0) top right,
linear-gradient(#000, #000) padding-box bottom right,
linear-gradient(45deg, transparent 2em, #000 0) bottom left;
/*I have avoided adding -webkit-, -moz and -0 prefixs for linear-gradient. You may put them in later to be extra safe*/
background-size: 50% 50%; /* There is no reason to paint the upper left quadrant, so I didn't. */
background-repeat: no-repeat;
-webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box;
/* Many people use border-box as default these days. Unfortunately, the box cannot be sized using border-box settings with the combination of padding in ems and percentages. So this is reset to content-box, just in case. */
z-index: -1; /* To keep the shadow behind the div*/
<div>This is a short sentence to demonstrate that our little div is responsive.</div>
Here's a little implementation, inspired by #Vitorino fernandes, in stylus...
offset = 10
border = 3
.offsetbox
margin offset
padding offset
text-align center
box-shadow inset 0 0 0 unit(border,px) black
background white
display inline-block
position relative
&:after,
&:before
content ''
background black
position absolute
&:after
width 100%
height offset
transform translatey(100%) skewx(-45deg)
right (offset/2)
bottom 0
&:before
height 100%
width offset
transform: translatex(-100%) skewy(-45deg)
left 0
top (offset/2)
I added some clip paths to #Vittorino fernandes code, to avoid white space between pseudos and make it sharper.
I added some 1px adjustments to avoid bad svg rendering problems.
You can use the variable called shadow-dimension to set the shadow width and height.
I Put it on a codePen:
https://codepen.io/silviamalavasi/pen/XWqeWEq
:root {
--shadow-dimension: 20px;
--blue: #0039a6;
}
.box-container {
position: relative;
}
.box-container>div {
border: 2px solid var(--blue);
}
.box-container>div:after, .box-container>div:before {
content: '';
background-color: var(--blue);
position: absolute;
}
.box-container>div:before {
width: calc(var(--shadow-dimension) + 1px);
height: calc(100% + 100px + 1px);
left: calc(var(--shadow-dimension) * -1);
transform: skewy(-45deg);
top: calc(0.5*var(--shadow-dimension));
clip-path: polygon(0% 0%, 100% 0%, 100% calc(100% - 100px - 2px + var(--shadow-dimension)), 0% calc(100% - 100px - 2px));
}
.box-container>div:after {
width: calc(100% + 100px);
height: calc(var(--shadow-dimension) + 1px);
left: calc(-0.5*var(--shadow-dimension) - 100px);
bottom: 1px;
transform: translateY(100%) skewx(-45deg);
clip-path: polygon(100px 0%, 100% 0%, 100% 100%, calc(100px + 2px) 100%);
}

Seamless box-shadow for blurry effect

I am trying to make a div look like a white glowing circle with no edges. The css is achieved with:
body {
background: #000;
}
div {
border-radius: 50%;
/* makes the div background circular */
background: white;
height: 275px;
width: 275px;
box-shadow: 0px 0px 220px 279px #fff;
/* creates glow effect */
}
<div></div>
When there is a problem it looks like this:
The problem is that on some screens, there is a line separating the circle from the glow. I am trying to achieve a seamless glow without the circle. I have tried filter:blur but this is not an option since it blurs the logo image nested inside the div.
The problem is on the landing page of this site.
The buggy rendering in Chrome seems to be caused by the blur-radius and is hidden by the spread-radius; it seems to only occur with large blur-radius values. Through trial and error you can use the spread-radius to cover up the bug.
It's not perfect, but this works:
box-shadow: 0px 0px 140px 300px #FFF;
These are the changes that work on your site. Place the border radius and box shadow on the outer div to eliminate a gray ring.
#logo-outer {
margin: 10px auto;
width: 275px; /* increase width to match #logo */
background: none repeat scroll 0% 0% #FFF;
border-radius: 50%;
box-shadow: 0px 0px 140px 300px #FFF; /* change the box shadow blur and spread */
}
#logo {
height: 275px;
width: 275px;
background: none repeat scroll 0% 0% #FFF;
}
This is what it looks like in Chrome
Bug Workaround Example
body {
background: #000;
}
div {
border-radius: 50%;
height: 250px;
width: 250px;
box-shadow: 0 0 140px 300px #fff;
background: #FFF;
}
<div></div>

border causes div to overlap past 100% by 1 or 2px

I have our navigation bar set to 100%. The bar also has a 1px border on it. For some reason, the border causes the nav bar to stick out to the right by 1 or 2 pixels. I tried setting the border to 0 in Firebug and sure enough, it lined up correctly. Our site is here: http://clubschoicefundraising.com/
As you can see, the blue nav bar at the top stick out to the left side. I can remove the "right: 0" and then it sticks out to the right side. How do I prevent the border from causing the nav bar to stick out?
Update: As requested, here is my CSS for the nav:
nav
{
position: absolute;
right: 0;
top: 70px;
margin-top: 5px;
font-size: 1.3em;
font-weight: 600;
list-style: none;
width: 100%;
margin: 5px auto;
height: 43px;
padding: 0;
z-index: 10;
/* Background color and gradients */
background: #014464;
background: -moz-linear-gradient(top, #0272a7, #013953);
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#0272a7), to(#013953));
background: -ms-linear-gradient(top, #0272a7, #013953);
background: -moz-linear-gradient(top, #3C78B9, #28507B);
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#3C78B9), to(#28507B));
background: -ms-linear-gradient(top, #3C78B9, #28507B);
/* Borders */
border: 1px solid #002232;
box-shadow:inset 0px 0px 1px #edf9ff;
}
Explanation :
By default, borders are calculated outside a specified with on an element,that is why it overflows when you give your element a border.
Solution :
Use box-sizing:border-box; so that the border width is calculated inside the 100% and it won't overflow. (more info on box sizing on MDN)
box-sizing:border-box; is supported by IE8+ (see canIuse)
This is because the computed width of the element exceeds the available space inside its parent.
<div> elements - other than absolutely positioned ones - will take up the available width of their parent.
However in this particular instance that you have removed the element from normal flow by using absolute positioning, you could specify the width of the element - stretch the element - by left: 0; right: 0; declarations which is supposed to work on a large scale of web browsers.
Alternatively, you could use box-sizing: border-box; declaration to make the UAs calculate the width/height of the box including the borders and padding.
It's worth noting that the second approach is supported in IE 8 and above.
Add box-sizing: border-box to your nav
nav {
box-sizing: border-box;--> ADDED
position: absolute;
right: 0;
top: 70px;
margin-top: 5px;
font-size: 1.3em;
font-weight: 600;
list-style: none;
box-sizing: border-box;
width: 100%;
margin: 5px auto;
height: 43px;
padding: 0;
z-index: 10;
background: #014464;
background: -moz-linear-gradient(top, #0272a7, #013953);
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#0272a7), to(#013953));
background: -ms-linear-gradient(top, #0272a7, #013953);
background: -moz-linear-gradient(top, #3C78B9, #28507B);
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#3C78B9), to(#28507B));
background: -ms-linear-gradient(top, #3C78B9, #28507B);
border: 1px solid #002232;
box-shadow: inset 0px 0px 1px #edf9ff;
}
For more info about box-sizing you can refer to this link

display box shadow above the text

Let's say I have a simple div with some paragraphs inside.
I want to achieve a fading effect on the bottom of the div.
I have tried to set up a white shadow
box-shadow: inset 0 -15px 10px white;
but obviously this didn't work, since the box-shadow always appears under the text.
How can I accomplish this in pure CSS?
Thanks.
What about using the "after" css selector ? it even work with IE8 : http://caniuse.com/#search=after
.container{
position: relative;
height: 100px;
overflow: hidden;
}
.container:after{
content: "";
position: absolute; top: 0; bottom: 0; left: -15px; right: -15px;
box-shadow: inset white 0 -15px 10px;
}
I'm using negative left and right to put the inside box outside the main box to avoid the shadow on the sides.
I was able to replicate the effect with CSS only, but it's a little hackish:
http://jsfiddle.net/EaXTB/1/
I put two divs as siblings:
<div class="container">
<div class="shadow"></div>
<div class="copy">
<p>Lorem ipsum dolor sit amet, ...</p>
</div>
</div>
And positioned them absolutely:
.container { position:relative; }
.shadow {
-webkit-box-shadow: inset 0px -15px 10px 0px rgba(255, 255, 255, 1);
-moz-box-shadow: inset 0px -15px 10px 0px rgba(255, 255, 255, 1);
box-shadow: inset 0px -15px 10px 0px rgba(255, 255, 255, 1);
height: 200px;
width: 300px;
z-index: 100;
position:absolute;
}
.copy {
max-height: 200px;
width: 300px;
overflow: hidden;
z-index: 0;
position: absolute;
}
The only trouble is that for this to work, you must specify the height for the .shadow class. If it will always be the same size, then you can use this. Otherwise using a png overlay might be more effective.
Something like:
.shadow {
background: url(overlay.png) repeat-x bottom;
}
div {
height:300px;
color:red;
overflow-y: scroll;
}
div:after {
content: "";
box-shadow: 0px -50px 50px -50px #000 inset;
position:fixed;
top: 250px;
left:0;
width:100%;
height:50px;
overflow: hidden;
}
create a div below all your other divs and set a negative bottom margin to that div and a top drop shadow. You can do that or you can do what I have done. Save a png image with that fade and set it to an absolutely positioned div that sits at the bottom of your relatively positioned div that contains the text.

Resources