css rotate background from middle to corner - css

I want to achieve this in CSS, valid for all screen sizes:
From the left side to the middle of my screen the background should be blue, from the upper middle to the right bottom corner the background should be white.
This is what I got already:
<style>
.wrapper {
position: fixed;
z-index: 1;
width: 100%;
height: 100%;
background: #297fca;
}
.right {
position: fixed;
z-index: 2;
top: -70%;
right: -50%;
background: #fff;
width: 100%;
height: 100%;
transform: translateY(50%) rotate(45deg);
}
</style>
...
<div class="wrapper">
<div class="right">
</div>
</div>
This is working for some screen sizes but not a general solution.
I'm looking for a CSS only solution. If this isn't possible a SVG apporach is ok too.
Thanks in advance.

You can easily do this with linear-gradient. You need two of them, one will create a square shape to fill the first 50% and the second one will create the triangle shape to fill the remaining 50%.
body {
margin:0;
height:100vh;
background-image:
linear-gradient(#297fca,#297fca),
linear-gradient(to bottom left,transparent 49.8%,#297fca 50%);
background-repeat:no-repeat;
background-size:50.1% 100%; /* both gradient will fill 50% width and 100% height*/
background-position:
left, /* The first one placed on the left*/
right /* The second one placed on the right*/
}
If you don't want transparency you can do it like below:
body {
margin:0;
height:100vh;
background:
linear-gradient(to top right,transparent 49.8%,#fff 50%)
right -1px top 0
/50% 100%
no-repeat,
#297fca;
}

You could use the css clip-path property and give it the necessary fill rules. Try the snippet below:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
height: 100vh;
background: #297fca;
clip-path: polygon(0 0, 50% 0, 100% 100%, 0 100%);
}
<div class="container"></div>

Related

add black and white filter to specific portion of a child container

In the photo above where the gray container is set I want to add a high contrast black and white photo filter.
Iv tried scaling the opacity and using the filter css3 property but have had no success.
The body is the background image and the child container is the gray box. I want to just have the child show the black and white.
body{
background: url('../images/wtc.jpg') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
.profile-box{
background-color: grey;
width: 80%;
height: 60%;
margin-top: 180px;
margin-bottom: 100px;
}
Easiest solution, but least supported: backdrop-filter
The most straight-forward way, is to actually use the rather new backdrop-filter property. Unfortunately it is only supported in Safari (and Chrome Canary) so far.
body{
background: url('https://i.imgur.com/uh5YLj5.jpg') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
margin: 0;
padding: 0;
}
.profile-box{
width: 80%;
height: 60%;
/* Backdrop filter */
-webkit-backdrop-filter: grayscale(100%);
backdrop-filter: grayscale(100%);
/* Additional styles for positioning */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="profile-box"></div>
The code snippet above will render something similar to this on Safari:
Complicated solutions, but more cross-browser compatible
Using the deprecated clip:
An alternative solution that will see more support across browser is to use the clip: rect(...) property. This property has been, however, deprecated in favour of clip-path (see next section for the updated solution). Since you have specified on your code that you wanted a grayscale area that is 80% in width and 60% in height (relative to viewport, so that is equivalent to 80vw and 60vh), we can tune the arguments passed into clip: rect(...) as such:
clip: rect(30vh, 90vw, 70vh, 10vw);
The coordinates represent offset from the top/left corners of the page of the top, right, bottom, left edges of the clip rectangle. To center a 80vw horizontally, we need 10vw on left and right (adding up to 20vw). To center a 60vh vertically, we need 20vh on top and bottom (adding up to 40vh). This computes to:
20vh from the top (this is the TOP border measured from top)
90vw from the left (this is the RIGHT border measured from left)
80vh from the top (this is the BOTTOM border measured from top)
10vw from the left (this is the LEFT border measured from left)
The image below will help you explain the calculations more:
body{
background: url('https://i.imgur.com/uh5YLj5.jpg') no-repeat center center fixed;
background-size: cover;
margin: 0;
padding: 0;
}
.profile-box {
background: url('https://i.imgur.com/uh5YLj5.jpg') no-repeat center center fixed;
background-size: cover;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
filter: grayscale(100%);
clip: rect(20vh, 90vw, 80vh, 10vw);
}
<div class="profile-box"></div>
Using the new property, clip-path:
Even though it is a more modern standard compared to clip, it still suffers from non-support in IE or Edge. The arguments of clip-path: inset(...) are not comma-separated, unlike that of clip: rect(...), and it is slightly more intuitive to use because each edge is measure relative to the corresponding edge of the browser. In that case, using the same calculation logic we have established above, the arguments will be:
20vh from the top
10vw from the right
20vh from the bottom
10vw from the left
In other words, something like this:
clip-path: inset(20vh 10vw 20vh 10vw);
body{
background: url('https://i.imgur.com/uh5YLj5.jpg') no-repeat center center fixed;
background-size: cover;
margin: 0;
padding: 0;
}
.profile-box {
background: url('https://i.imgur.com/uh5YLj5.jpg') no-repeat center center fixed;
background-size: cover;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
filter: grayscale(100%);
clip-path: inset(20vh 10vw 20vh 10vw);
}
<div class="profile-box"></div>
What you are trying to do is usually a pretty hard thing to achieve with css but it is possible. I think this answer will help you:
TAKEN FROM https://stackoverflow.com/a/19382357/8312881
written by edensource
If it has to be dynamic, you should have some trouble, but you can
have somewhere to start with this :
HTML
<div class="background"></div>
<div class="mask">
<div class="bluredBackground"></div>
</div>
<div class="content"></div>
CSS
.content {
width: 70%;
height: 70%;
border:2px solid;
border-radius:20px;
position: fixed;
top: 15%;
left: 15%;
z-index:10;
background-color: rgba(168, 235, 255, 0.2);
}
.background {
width:100%;
height:100%;
background-image:url('http://www.travel.com.hk/region/time_95.jpg');
z-index:2;
position:fixed;
}
.bluredBackground {
width:100%;
height:100%;
display:block;
background-image:url('http://www.travel.com.hk/region/time_95.jpg');
z-index:1;
position:absolute;
top:-20%;
left:-20%;
padding-left:20%;
padding-top:20%;
-webkit-filter: blur(2px);
}
.mask {
width: 70%;
height: 70%;
border:2px solid;
border-radius:20px;
position: fixed;
top: 15%;
left: 15%;
z-index:10;
overflow:hidden;
}
FIDDLE
http://jsfiddle.net/sE4Fv/
FIDDLE with greyscale filter
http://jsfiddle.net/sE4Fv/926/
(you did not respond to my question in comments, so i still go with an average answer untill feedback shows ;) )
you can use an rgba() color if the matter is to darken your image.
A simple example with background or image to show the idea, a third example showing the use of the grayscale(X%) filter if the matter is turn blac & white the image:
.filter {
position: relative;
float: left;
width: 50%;
}
.filter:before {
content: '';
position: absolute;
top: 15%;
right: 5%;
bottom: 15%;
left: 5%;
background: rgba(0, 0, 0, 0.5);
}
.filter img {
display: block;
width: 100%;
}
.filter.bg {
box-sizing: border-box;
padding: 1.5% 2.5%;
background: url(http://lorempixel.com/1200/250/city/5) center / 100% auto;
}
.bg:before {
display: none;
}
.content {
min-height: 7.45vw;
height: 100%;
background: rgba(0, 0, 0, 0.5)
}
.grayscale .content {
background: url(http://lorempixel.com/1200/250/city/5) center / 50vw auto;
filter: grayscale(100%);
}
body {
margin: 0;
}
<div class="filter">
<img src="http://lorempixel.com/1200/250/city/5" alt="my nice City" /></div>
<div class="filter bg ">
<div class="content">Some content hover the bg </div>
</div>
<div class="filter bg grayscale ">
<div class="content">Some content hover the bg </div>
</div>
Your body is ok, just the .profile-box needs some fixes:
div.profile-box {
background: url('https://s3-us-west-1.amazonaws.com/powr/defaults/image-slider2.jpg') no-repeat center center fixed;
background-size: cover;
filter: grayscale(100%);
// width & height etc...
}
Attach your background in the box as well and add filter: grayscale(100%)
Demo

How to set background image of outer div only to the right of inner div?

I have 2 divs, one stretches over the entire screen, other is centered within.
<div id="outer">
<div id="inner">
</div>
</div>
CSS looks like this:
#outer {
/* This line is important */
background: black url("https://placehold.it/1x50") repeat-x;
/* irrelevant */
height: 50px;
width: 100%;
}
#inner {
width: 1000px;
height: 50px;
margin: 0 auto;
background-color: #eee;
}
What I want to do is set the background of the outer div, but only to the right of the inner div. Currently a 1px image is set to repeat itself over the entire outer div, but I need it to go only to the right.
When done right, background will be black on left of inner div and grey on right (because placehold.it image is grey).
I can change HTML if necessary.
You can use a linear gradient background with an abrupt color change at 50% to the body:
#outer {
background: linear-gradient(to right, #000 0%, #000 50%, #ccc 50%, #ccc 100%);
height: 50px;
width: 100%;
}
Here's the result: http://codepen.io/anon/pen/JWjQzm
Addition:
With a background image, you can combine a plain color background and an image. But you can't repeat the image on the x-axis, so you'd have to have an image that covers at least the background width at the right side:
background: #000 url(http://placehold.it/200x50/fa0) right repeat-y;
http://codepen.io/anon/pen/jBOgya
Another addition/version after comment:
You didn't yet say what kind of image that is, but if it's just a repeated 1x50px image as in you example, you might as weel stretch it to half the screen width by adding background-size: 50% 100%; - see codepen linked below:
http://codepen.io/anon/pen/OpJKKO
Try this code on your codepen
HTML
<div id="outer">
<div id="inner">
</div>
</div>
CSS
#outer {
background: black;
height: 50px;
width: 100%;
position: relative;
}
#inner {
width: 1000px;
height: 50px;
margin-left: auto;
margin-right: auto;
background-color: #eee;
}
#inner:after{
content: "";
background: url(http://placehold.it/1x50/fa0) repeat-x;
top: 0px;
right:0px;
height: 50px;
width: calc(50% - 500px);
position: absolute;
}

background-position percentage not working [duplicate]

This question already has answers here:
Using percentage values with background-position on a linear-gradient
(2 answers)
Closed 3 years ago.
Everywhere I read says this should be working fine, but for some reason it's not.
This was to fix someone else's issue so fixing it doesn't matter to me, I just want to know why. The problem is on .br .bg-image. I know I'm trying to use calc() but using a simple background-position: 50% doesn't work either.
http://jsfiddle.net/uLaa9fnu/2/
html {
height: 100%;
width: 100%;
}
body {
margin: 0px;
height: 100%;
width: 100%;
overflow: hidden;
}
.bg-image {
height: 600px;
width: 800px;
background-image: url('http://media1.santabanta.com/full1/Outdoors/Landscapes/landscapes-267a.jpg');
background-size: 100%;
background-repeat: no-repeat;
}
.relative {
position: relative;
}
.containeroverlay {
background-color: rgba(0, 0, 0, 0.6);
height: 100%;
width: 100%;
}
.framesizer {
height: 340px;
width: 300px;
overflow: hidden;
position: absolute;
}
.frame {
background-image: url('http://i.imgur.com/4AcIXsD.png');
background-repeat: no-repeat;
background-size: 100%;
height: 340px;
width: 300px;
}
.tl {
top: 30px;
left: 30px;
}
.tl .bg-image {
background-position: right 30px bottom 30px;
}
.br {
top: calc(100% - 340px - 30px);
/* Height of frame, plus 30px spacing */
left: calc(100% - 300px - 30px);
/* Width of frame, plus 30px spacing */
}
.br .bg-image {
background-position: right calc(800px - 300px - 30px) bottom calc(600px - 340px - 30px);
/* Background Position doesn't like percentages for some reason */
}
<div class="bg-image">
<div class="containeroverlay relative">
<div class="framesizer tl">
<div class="bg-image">
<div class="frame"></div>
</div>
</div>
<div class="framesizer br">
<div class="bg-image">
<div class="frame"></div>
</div>
</div>
</div>
</div>
Solving the problem
After some fiddling I've found what is causing the issue. background-position stops working when the background is as big (or bigger) as the frame it contains.
This is also why dognose's solution works. It removes the background-size.
As proof, I've changed the CSS of the .br-frame and .br .bg-image to the following:
.br {
top:calc(100% - 340px - 30px);
left:calc(100% - 300px - 30px);
}
.br .bg-image {
background-position: calc(100% + 30px) calc(100% + 30px);
/* 100% puts it bottom right, + 30px offset from .br */
background-position: right -30px bottom -30px;
/* or simply use this */
height: 100%;
width: 100%;
background-size: 800px 600px;
}
This way the background-size doesn't equal the frame anymore, causing the background-position to work as it is supposed to.
See the fiddle
The why
The reason it doesn't work with percentages, is because the background-position depends on the background-size, literally. Because background-position: 0% 0%; is top left, and background-position: 100% 100%; is bottom right. If the background image is as big as it's containing frame, there is no more difference between 0% and 100%.
Using this theory in combination with calc(), all it does is:
calc(100% - 340px - 30px) place it to the right (100%), which doesn't move it at all, then move it a total of 370px (-340px - 30px) to the left.
In your case it goes to the right, because you prefixed right before your calc().
background-position
Initial value 0% 0%
refer to the size of the background positioning area minus size of
background image; size refers to the width for horizontal offsets and
to the height for vertical offsets
So any differences on the size of the background image and the size of the element
are welcome and that what makes background positioning work with percentages. Otherwise they don't.
Example:
Consider an image with a size of 500X500 px;
Using a background-position: 50% 50%;
If your div has a width of 600px;
your background image will be shifted to the right by
50% * (600px - 500px) that is 50px
Similarly, if the div has a height of 700px your background image will be shifted down by
50% * (700px - 500px) that is 100px
div{
background-image: url(https://i.imgur.com/gcnJ2Qi.png);
background-repeat: no-repeat;
background-position: 50% 50%;
border: solid grey;
width: 600px;
height:700px;
}
<div></div>
In case the div is narrower than the image
Now you're div element is 300X400 px,and you want to position your background image the same as before (50px right and 100px down)
You will need to specify a negative background-position: -25% -100%;
Because -25% * (300-500) = 50px and -100% (400-500) = 100px
div{
background-image: url(https://i.imgur.com/gcnJ2Qi.png);
background-repeat: no-repeat;
background-position: -25% -100%;
border: solid grey;
width: 300px;
height:400px;
}
<div></div>
In the case where both div and image have the same size:
Any percentage you specify at background-position would be multiplied by zero.
And the image will be always aligned with the top left corner of the div. To fix that make the image smaller or bigger by resetting background-size:80% or 120%;
div{
background-image: url(https://i.imgur.com/gcnJ2Qi.png);
background-repeat: no-repeat;
background-position: 50% 100%;
border: solid grey;
width: 500px;
height:500px;
background-size:80%;
}
<div></div>
The docs
GEspinha is somewhat right. This example works as you might expect:
.br .bg-image {
background: url('http://media1.santabanta.com/full') 50% 50%;
}
while having this - it wont work.
.br .bg-image {
background-position:50% 50%;
}
http://jsfiddle.net/gtj5p0px/ (if this is your expeted output for the bottom right frame)

Underlining some pixels shorter than the headline [duplicate]

I need to create an underline effect with a bottom border that is smaller than the h2 title's width. Usually I don't upload images but I figure it might help explaining the question a bit further:
You could use a pseudo-element for this. (example)
.pseudo_border {
position:relative;
display:inline-block;
}
.pseudo_border:after {
content:'';
position:absolute;
left:0; right:0;
top:100%;
margin:10px auto;
width:50%;
height:6px;
background:#00f;
}
Just absolutely position a pseudo-element relative to the parent element. Position it 100% from the top and use a combination of left:0; right:0 and a margin of auto for horizontal centering. Modify the height/width of the element accordingly and change the margin-top for the spacing.
Other approach :
Box shadow with a negative spread radius :
body{text-align:center;}
h2{
font-size:40px;
color:#409FB3;
display:inline-block;
height:50px;
box-shadow: 0 25px 0 -23px #5CC7A8;
}
<h2>Some title</h2>
Note : you need to make sure that - spread-radius x2 < height otherwise the box-shadow will have 0 height and disapear.
You can also do this using linear-gradient. In this method, a small background image is created using gradients such that it is transparent for the first and last 25% while the rest 50% has the color (thus making it look like it is 50% of the actual h2 text). This background is then positioned at the bottom of the element to make it look like a bottom border. The size of the border can be varied by modifying the background-size.
The effect would hold good even when the amount of text within the h2 varies. The main drawback however is the relatively poor browser support for gradients as compared to the pseudo-element or the box-shadow approach.
Note: The use of the script in the answer is only for avoiding browser prefixes :)
h2{
display: inline-block;
text-align: center;
padding: 10px 10px 15px; /* bottom padding should be higher to make up for pseudo border height */
background: linear-gradient(90deg, transparent 25%, lightseagreen 25%, lightseagreen 75%, transparent 75%);
background-size: 100% 5px;
background-position: 0% 100%;
background-repeat: no-repeat;
}
.semitransparent{
background: linear-gradient(90deg, transparent 25%, lightseagreen 25%, lightseagreen 75%, transparent 75%), linear-gradient(90deg, transparent 0%, rgba(50,50,50,0.25) 0%);
background-size: 100% 5px, 100% 100%;
background-position: 0% 100%, 0% -5px;
background-repeat: no-repeat;
}
.colored{
background: linear-gradient(90deg, transparent 25%, lightseagreen 25%, lightseagreen 75%, transparent 75%), linear-gradient(90deg, transparent 0%, aliceblue 0%);
background-size: 100% 5px, 100% 100%;
background-position: 0% 100%, 0% -5px;
background-repeat: no-repeat;
}
/* Just for demo */
body{
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
font-family: Calibri, Tahoma;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<h2>Some Text</h2><br/>
<h2 class='semitransparent'>Some Lengthy Text</h2><br/>
<h2 class='colored'>Some more examples yay!!</h2>
You could use a sort of 'fake' border by simply wrapping a div around it and making a border div after the title
JSFiddle
HTML
<div id="border-wrapper">
<h2>My address</h2>
<div id="border"></div>
</div>
CSS
#border-wrapper{
position:relative;
display:inline-block;
}
#border{
position: relative;
width: 50%;
height: 2px;
background-color: blue;
margin: 0 auto;
}
Almost all of the solutions I've seen for this effect in the past have relied on positioning - but using display: flex we can achieve it pretty easily. The below is an example of a heading, but it can be used on any element. Just bear in mind the nature of flex-direction: column will stack any child elements.
HTML
<h3 class="heading">Hey presto! We have an underline.</h3>
CSS
.heading {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.heading:after {
content: '';
border-bottom: 1px solid #ccc;
padding-top: 10px;
width: 50px;
}
Note you may have to add vendor prefixes for flex depending on browser support (mostly previous versions of IE, of course) https://caniuse.com/#search=flex
h2 ::after {
background: #f1991b none repeat scroll 0 0;
content: "";
display: block;
height: 2px;
margin-top: 15px;
width: 50px;
}
<style>
.main{
text-align:center;
}
.title{
font-weight: 300;
display: inline-block;
padding-bottom: 15px;
position: relative;
}
.title::after {
content: "";
position: absolute;
width: 50%;
height: 1px;
bottom: 0;
left: 0;
border-bottom: 3px solid #ff5533;
right: 0;
margin: 0 auto;
}
</style>
<div class="main">
<h1 class="title">
Your Title
</h1>
</div>

Any way to limit border length?

Is there any way to limit the length of a border. I have a <div> that has a bottom border, but I want to add a border on the left of the <div> that only stretches half of the way up.
Is there any way to do so without adding extra elements on the page?
CSS generated content can solve this for you:
div {
position: relative;
}
/* Main div for border to extend to 50% from bottom left corner */
div:after {
content: "";
background: black;
position: absolute;
bottom: 0;
left: 0;
height: 50%;
width: 1px;
}
<div>Lorem Ipsum</div>
(note - the content: ""; declaration is necessary in order for the pseudo-element to render)
#mainDiv {
height: 100px;
width: 80px;
position: relative;
border-bottom: 2px solid #f51c40;
background: #3beadc;
}
#borderLeft {
border-left: 2px solid #f51c40;
position: absolute;
top: 50%;
bottom: 0;
}
<div id="mainDiv">
<div id="borderLeft"></div>
</div>
The ::after pseudo-element rocks :)
If you play a bit you can even set your resized border element to appear centered or to appear only if there is another element next to it (like in menus). Here is an example with a menu:
#menu > ul > li {
position: relative;
float: left;
padding: 0 10px;
}
#menu > ul > li + li::after {
content:"";
background: #ccc;
position: absolute;
bottom: 25%;
left: 0;
height: 50%;
width: 1px;
}
#menu > ul > li {
position: relative;
float: left;
padding: 0 10px;
list-style: none;
}
#menu > ul > li + li::after {
content: "";
background: #ccc;
position: absolute;
bottom: 25%;
left: 0;
height: 50%;
width: 1px;
}
<div id="menu">
<ul>
<li>Foo</li>
<li>Bar</li>
<li>Baz</li>
</ul>
</div>
With CSS properties, we can only control the thickness of border; not length.
However we can mimic border effect and control its width and height as we want with some other ways.
With CSS (Linear Gradient):
We can use linear-gradient() to create a background image(s) and control its size and position with CSS so that it looks like a border. As we can apply multiple background images to an element, we can use this feature to create multiple border like images and apply on different sides of element. We can also cover the remaining available area with some solid color, gradient or background image.
Required HTML:
All we need is one element only (possibly having some class).
<div class="box"></div>
Steps:
Create background image(s) with linear-gradient().
Use background-size to adjust the width / height of above created image(s) so that it looks like a border.
Use background-position to adjust position (like left, right, left bottom etc.) of the above created border(s).
Necessary CSS:
.box {
background-image: linear-gradient(purple, purple),
// Above css will create background image that looks like a border.
linear-gradient(steelblue, steelblue);
// This will create background image for the container.
background-repeat: no-repeat;
/* First sizing pair (4px 50%) will define the size of the border i.e border
will be of having 4px width and 50% height. */
/* 2nd pair will define the size of stretched background image. */
background-size: 4px 50%, calc(100% - 4px) 100%;
/* Similar to size, first pair will define the position of the border
and 2nd one for the container background */
background-position: left bottom, 4px 0;
}
Examples:
With linear-gradient() we can create borders of solid color as well as having gradients. Below are some examples of border created with this method.
Example with border applied on one side only:
.container {
display: flex;
}
.box {
background-image: linear-gradient(purple, purple),
linear-gradient(steelblue, steelblue);
background-repeat: no-repeat;
background-size: 4px 50%, calc(100% - 4px) 100%;
background-position: left bottom, 4px 0;
height: 160px;
width: 160px;
margin: 20px;
}
.gradient-border {
background-image: linear-gradient(red, purple),
linear-gradient(steelblue, steelblue);
}
<div class="container">
<div class="box"></div>
<div class="box gradient-border"></div>
</div>
Example with border applied on two sides:
.container {
display: flex;
}
.box {
background-image: linear-gradient(purple, purple),
linear-gradient(purple, purple),
linear-gradient(steelblue, steelblue);
background-repeat: no-repeat;
background-size: 4px 50%, 4px 50%, calc(100% - 8px) 100%;
background-position: left bottom, right top, 4px 0;
height: 160px;
width: 160px;
margin: 20px;
}
.gradient-border {
background-image: linear-gradient(red, purple),
linear-gradient(purple, red),
linear-gradient(steelblue, steelblue);
}
<div class="container">
<div class="box"></div>
<div class="box gradient-border"></div>
</div>
Example with border applied on all sides:
.container {
display: flex;
}
.box {
background-image: linear-gradient(purple, purple),
linear-gradient(purple, purple),
linear-gradient(purple, purple),
linear-gradient(purple, purple),
linear-gradient(steelblue, steelblue);
background-repeat: no-repeat;
background-size: 4px 50%, 50% 4px, 4px 50%, 50% 4px, calc(100% - 8px) calc(100% - 8px);
background-position: left bottom, left bottom, right top, right top, 4px 4px;
height: 160px;
width: 160px;
margin: 20px;
}
.gradient-border {
background-image: linear-gradient(red, purple),
linear-gradient(to right, purple, red),
linear-gradient(to bottom, purple, red),
linear-gradient(to left, purple, red),
linear-gradient(steelblue, steelblue);
}
<div class="container">
<div class="box"></div>
<div class="box gradient-border"></div>
</div>
Screenshot:
for horizontal lines you can use hr tag:
hr { width: 90%; }
but its not possible to limit border height. only element height.
Another way of doing this is using border-image in combination with a linear-gradient.
div {
width: 100px;
height: 75px;
background-color: green;
background-clip: content-box; /* so that the background color is not below the border */
border-left: 5px solid black;
border-image: linear-gradient(to top, #000 50%, rgba(0,0,0,0) 50%); /* to top - at 50% transparent */
border-image-slice: 1;
}
<div></div>
jsfiddle: https://jsfiddle.net/u7zq0amc/1/
Browser Support:
IE: 11+
Chrome: all
Firefox: 15+
For a better support also add vendor prefixes.
caniuse border-image
Borders are defined per side only, not in fractions of a side. So, no, you can't do that.
Also, a new element wouldn't be a border either, it would only mimic the behaviour you want - but it would still be an element.
This is a CSS trick, not a formal solution. I leave the code with the period black because it helps me position the element. Afterward, color your content (color:white) and (margin-top:-5px or so) to make it as though the period is not there.
div.yourdivname:after {
content: "";
border-bottom: 1px solid grey;
width: 60%;
display: block;
margin: 0 auto;
}
Article about this issue: https://www.steckinsights.com/shorten-length-border-bottom-pure-css/
Another solution is you could use a background image to mimic the look of a left border
Create the border-left style you require as a graphic
Position it to the very left of your div (make it long enough to handle roughly two text size increases for older browsers)
Set the vertical position 50% from the top of your div.
You might need to tweak for IE (as per usual) but it's worth a shot if that's the design you are going for.
I am generally against using images for something that CSS inherently provides, but sometimes if the design needs it, there's no other way round it.
You can define one border per side only. You would have to add an extra element for that!

Resources