How to fix blurry egdes on blurred background in css - css

I would like to have a blurred background, while the edges of this Background shall not be blurred. I want the blurred image to entirly fill the background of its paaernt container.
My current solution is:
HTML
<div class="wrapper">
<div class="background"></div>
<div class="text">Lorem Ipsum dolor sit</div>
</div>
CSS
.wrapper {
display: block;
position: relative;
width: 240px;
height: 300px;
overflow: hidden;
border: 1px solid blue;
}
.wrapper .background {
position: absolute;
display: block;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('http://photo.elsoar.com/wp-content/images/Strawberry-afbeelding.jpg');
-webkit-filter: blur(5px);
-moz-filter: blur(5px);
-o-filter: blur(5px);
-ms-filter: blur(5px);
filter: blur(5px);
}
.wrapper .text {
position: absolute;
display: block;
top: 40%;
left: 0;
width: 100%;
height: 60%;
background: rgba(0,130,120,0.5);
color: white;
padding: 10px;
font-size: 2rem;
}
How can I get "no blurry edges", but a blurred image fillingth entire "blue" box?
Thanks a lot.
Working sample:
http://codepen.io/anon/pen/alnDr

The only solution I can think of is using clip property, however it's very tricky, it requires the element to have absolute position. In this case the width clipped should be less than the width of the element, if it's equal to the element's width, it can't clip the blur (strange enough). So we have to set it about 1px less than the element's width, however the border will be broken, so we have to use box-shadow to mimic the border. You can also wrap some element around and set the border for the outer element instead:
.wrapper {
display: block;
position: absolute;
width: 240px;
height: 300px;
overflow: hidden;
box-sizing:border-box;
clip:rect(0,239px,300px,0);
box-shadow:0 0 0 1px blue inset,
-2px 0 0 0 blue inset;
}
Updated Demo.
Another solution can also be used if the background around your div is a solid color, in such a case you can use box-shadow to cover the outer blur like this:
.wrapper {
display: block;
width: 240px;
height: 300px;
overflow: hidden;
position:relative;
border:1px solid blue;
box-shadow:0 0 0px 10px white; /* the surrounding color is white */
}
Note that the inner blurry image should be set with z-index:-1 so that it comes behind the box-shadow, otherwise the box-shadow can't cover the outer blur.
Demo 2

Related

outline to only one side of div

I have tried few but is there a way to create an outline to right side of the div?
somthing like the purple line in the below image
https://unsee.cc/geduzopi/
use a pseudo element absolutely positioned to the right of the parent, then use translateX() to push it outside of the parent.
div {
display: inline-block;
width: 5em;
background: orange;
text-align: center;
position: relative;
}
div:after {
content: '';
width: .5em;
background: purple;
position: absolute;
right: 0; top: 0; bottom: 0;
transform: translateX(200%);
<div>1</div>
You can use border-right. For example
border-right: aqua 2pt solid;
See
https://www.w3schools.com/cssref/pr_border-right.asp
If you want to create an outline on one side and NOT a border, you can use box-shadow with inset like I did in my codepen example below. My example is good to look at if you have a border radius.
https://codepen.io/drewkiimon/pen/qeWQVx
div {
background: pink;
height: 250px;
width: 250px;
box-shadow: inset 0 1px black;
}
<div>
</div>

css transparent shape over image

This is what i am trying to achive
i have :
#image1 {
position: absolute;
bottom: 0px;
align-self: auto;
background-color: #dc022e;
width: 340px;
height: 100px;
border-radius: 50% / 100%;
border-bottom-left-radius: 0;
/*transform: rotate(10deg);*/
border-bottom-right-radius: 0;
opacity: 0.8;
}
#image2 img {
width: 80%;
}
<div>
<div id="image2">
<img src="http://t1.gstatic.com/images?q=tbn:ANd9GcThtVuIQ7CBYssbdwtzZjVLI_uw09SeLmyrxaRQEngnQAked5ZB">
</div>
<div id="image1"></div>
</div>
Finally I don't know how to make it rotated and with the margins cut like in the picture
A Quick example of this would use a pseudo element and have the image set in the background.
div {
position: relative;
height: 300px;
width: 500px;
background: url(http://lorempixel.com/500/300);/*image path*/
overflow: hidden;/*hides the rest of the circle*/
}
div:before {
content: "";
position: absolute; /*positions with reference to div*/
top: 100%;
left: 50%;
width: 0;/*define value if you didn't want hover*/
height: 0;
border-radius: 50%;
background: tomato;/*could be rgba value (you can remove opacity then)*/
opacity: 0.5;
transform: translate(-50%, -50%);/*ensures it is in center of image*/
transition: all 0.4s;
}
/*Demo Only*/
div:hover:before {/*place this in your pseudo declaration to remove the hover*/
height: 100%;
width: 150%;/*this makes the shape wider than square*/
transform: translate(-50%, -50%) rotate(5deg);/*ensures it is in center of image + rotates*/
}
div {/*This stuff is for the text*/
font-size: 40px;
line-height: 300px;
text-align: center;
}
<div>HOVER ME</div>
Instead of nested elements, you can just use a pseudo element. This is placed at the bottom of the container div. For this to work, you need position:relative and overflow:hidden on the container div. Also, pseudo elements always need the content declaration.
To modify the border radius, you just play around with left | width | height of the pseudo element. You don't need any rotation.
Instead of hex color and opacity you can as well use the "new" color space rgba(r,g,b,a) where a is the opacity value.
For the passepartout you simply use the border declaration.
#image2{
position:relative;
border:10px solid #888;
overflow:hidden;
box-shadow:0 0 4px #aaa;
}
#image2::after {
content:"";
display:block;
position: absolute;
bottom: 0;left:-10%;
background-color: #dc022e;
width: 120%;
height: 60%;
border-radius: 100% 100% 0 0;
opacity: 0.8;
}
#image2 img {
width: 100%;
display:block;
position:relative;
}
<div id="image2">
<img src="http://t1.gstatic.com/images?q=tbn:ANd9GcThtVuIQ7CBYssbdwtzZjVLI_uw09SeLmyrxaRQEngnQAked5ZB">
</div>
You can just use position: absolute for your image and position: relative for your overlay, adjusting the top position and width according to your needs. Here's a Fiddle. Hope this helps!
Edit: Here's an updated version of the Fiddle demonstrating border and overflow properties on the img container. As CBroe mentioned, rotating a circle is probably not a good use of your time in this case. Also, I definitely agree that using a pseudo element is a much cleaner approach than nesting images.

How to position vertically a repeat-y image background?

I have this code:
background:url("someimage.gif") repeat-y 50px right;
the problem here is that I need the background to start 50px from top so there is a 50px space between the image and the top but that wont happen. I know very well that the image would position right if not repeated but I need it to be repeated vertically. Is there any way around? How can I achieve that space between top and the start of the repeated image?
There a way to fake it if there is nothing in that top space.
Apply 50px (or your chosen value) of padding-top to the div.
The apply the background as usual (repeat-y) but clip the background to the content-boxof the div.
Background-clip # MDN
div {
background: url(http://placekitten.com/50/50) repeat-y;
padding-top: 50px;
height: 50vh;
background-clip: content-box;
width:50vw;
margin:2em auto;
border:1px solid red;
}
<div></div>
OR
Use a position pseudo-element suitably sized/positioned
div {
height: 50vh;
width: 50vw;
margin: 2em auto;
border: 1px solid red;
position: relative;
}
div:before {
content: '';
position: absolute;
width: 100%;
height: calc(100% - 50px);
background: url(http://placekitten.com/50/50) repeat-y;
top: 50px;
left: 0;
}
<div></div>

Square with rounded corners and indented curved border

I was wondering if it is possible to make a square with round corners and a indented border in pure CSS.
Currently I have this:
#custom-square {
position: relative;
display: block;
width: 75px;
height: 75px;
border: 2px solid #8A6EF1;
border-radius: 10px;
background-color: white;
}
Considering the hassle and amount of code needed to align double curves with CSS, SVG seems way more appropriate. A few other reasons to go for svg here are :
control of the path (color, width, curve...)
control the fill with a plain color, gradient or image
less code
you can display it over a non plain background (gradient or image)
maintain the boundaries of the shape for user interactions (hover, click...)
Here is a basic example using an inline svg with a path element.
The curves are drawn with Cubic Bezier curves :
svg{width:30%;}
<svg viewbox="0 0 10 10">
<path d="M1.5 0.5 Q5 1 8.5 0.5 Q9.5 0.5 9.5 1.5 Q9 5 9.5 8.5 Q9.5 9.5 8.5 9.5 Q5 9 1.5 9.5 Q0.5 9.5 0.5 8.5 Q1 5 0.5 1.5 Q0.5 0.5 1.5 0.5z"
fill="none" stroke-width="0.2" stroke="#8A6FF2" />
</svg>
Another pure CSS approach for creating this border would be to make use of border-image property. All that is required is create an image with the required border shape and set it to an element using the border-image-source property.
.shape.large {
height: 300px;
width: 300px;
border-image-source: url(http://i.stack.imgur.com/Qkh6A.png);
border-image-width: 34px; /* the width of the border portions in the image - refer to image at the end of the answer for the exact portion details*/
border-image-slice: 34; /* equal to border-image-width */
border-width: 34px; /* equal to border-image-width */
}
.shape.small {
height: 100px;
width: 100px;
border-image-source: url(http://i.stack.imgur.com/Mra4B.png);
border-image-width: 14px;
border-image-slice: 14;
border-width: 14px;
}
.shape.small.fill {
background: aliceblue content-box;
border-image-source: url(http://i.stack.imgur.com/Ovj03.png);
border-width: 14px;
}
/* Just for demo */
body {
background: url(http://lorempixel.com/800/800/abstract/2);
}
.shape.small {
float: left;
}
.shape.large {
clear: both;
}
<div class='shape small'>Some content</div>
<div class='shape small fill'>Some content</div>
<div class='shape large'>Some content</div>
At present this method is definitely not much advantageous compared to SVG but it is an option and in my opinion is better than the other CSS only approaches that are possible.
The advantages of this approach are:
Very minimal and low complexity code.
Better control over the curves and their radii (like with SVG) because the image with the required border curvature can be created separately.
Can be placed on top of an image or a gradient background.
Can be made to degrade gracefully (into a solid square border) in browser's that don't support it.
The drawbacks are:
The container is still a square and so hover effects will not be restricted to the boundaries of the shape unlike with SVG.
Adding solid color fill to the shape is possible (by using a filled version of the image) but adding a gradient or image fill is tricky because borders are still blocks (that is, there are transparent areas on either side of the curves).
The output is responsive but as dimensions increase or decrease beyond a threshold, the shape starts to look a bit compressed or stretched. So, this is more suited for break-point based design.
The browser support is not bad but is not great either. It works in Chrome, Firefox, Safari, Opera and IE11+.
Calculation of Border Image Width:
The width or height of border area (which becomes the border-image-width) is nothing but the width of the portion highlighted in the below image.
This draft mock up is as close as i could get it to pure CSS, but still requires a nested div. You would need to tweak the sizing / radius for the before / after circles.
Pen
div {
position: absolute;
top: 100px;
left: 100px;
width: 100px;
height: 100px;
border: 4px solid purple;
border-radius: 30px;
//overflow: hidden;
box-sizing: border-box;
&:before {
position: absolute;
top: -4px;
left: -94px;
content: ' ';
width: 100px;
height: 100px;
border: 4px solid purple;
border-radius: 50px;
box-sizing: border-box;
background-color: white;
clip: rect(0px, 100px, 100px, 90px);
}
&:after {
position: absolute;
top: -4px;
right: -94px;
content: ' ';
width: 100px;
height: 100px;
border: 4px solid purple;
border-radius: 50px;
box-sizing: border-box;
background-color: white;
clip: rect(0px, 10px, 100px, 0px);
}
}
div > div {
position: absolute;
top: -4px;
left: -4px;
transform: rotate(90deg);
border-color: transparent;
}
SVG is probably the way to go here, but here's a pretty close approximation in pure CSS. It could be made even better by increasing the size of the outer circles.
#middle {
width: 96px;
height: 96px;
border-radius: 10px;
background-color: green;
border: 2px solid #8A6EF1;
}
.outside {
width: 100px;
height: 100px;
position: relative;
overflow: hidden;
margin: 0;
padding: 0;
}
.cutout {
width: 96px;
height: 96px;
border-radius: 50%;
background-color: white;
border: 2px solid #8A6EF1;
}
#top {
top: -100px;
height: 10px;
}
#right {
top: -110px;
left: 90px;
width: 10px;
}
#bottom {
top: -120px;
height: 10px;
}
#left {
top: -220px;
width: 10px;
}
#top > .cutout {
margin-top: -90px;
}
#left > .cutout {
margin-left: -90px;
}
<div id="wrapper">
<div id="middle">
</div>
<div id="top" class="outside">
<div class="cutout">
</div>
</div>
<div id="right" class="outside">
<div class="cutout">
</div>
</div>
<div id="bottom" class="outside">
<div class="cutout">
</div>
</div>
<div id="left" class="outside">
<div class="cutout">
</div>
</div>
</div>

Is it possible to create this irregular quadrilateral with CSS?

I've tried the perspective solution here How to transform each side of a shape separately? but can't get it to work probably due to the irregularness of the shape. Only the top and right side columns are slanted, vertical and bottom are straight. How can I do this with CSS?
Using CSS borders you can create triangles and trapezoids.
You can achieve your shape joining a triangle and a trapezoid.
.triangle {
border: 0 solid red;
border-left-width: 500px;
border-top-width: 30px;
border-top-color: transparent;
}
.trapezoid {
border: 0 solid red;
width: 500px;
border-bottom-width: 150px;
border-right-width: 30px;
border-right-color: transparent;
}
<div class="triangle"></div>
<div class="trapezoid"></div>
Method 1: Clip path
You could make use of CSS clip-path feature to clip a rectangle into the required polygon shape.
div {
box-sizing: border-box;
height: 150px;
width: 250px;
background: red;
padding: 10px;
-webkit-clip-path: polygon(0% 0%, 90% 10%, 100% 100%, 0% 100%);
clip-path: polygon(0% 0%, 90% 10%, 100% 100%, 0% 100%);
}
div#image {
background: url(http://lorempixel.com/400/200);
}
/* Just for demo */
div{
float: left;
margin: 10px;
transition: all 1s;
}
div:hover{
height: 200px;
width: 300px;
}
<div>Some text</div>
<div id="image"></div>
Pros:
Supports non-solid color fills inside the shape and also allow text to be present inside.
The shape is responsive and can adapt even if the container's dimensions change.
Cons:
Poor browser support for the CSS clip-path feature. This can be overcome by using inline SVG for the clip-path like in the below snippet as this has much better browser support.
div {
box-sizing: border-box;
height: 150px;
width: 250px;
padding: 10px;
background: red;
-webkit-clip-path: url(#clip);
clip-path: url(#clip);
}
div#image {
background: url(http://lorempixel.com/400/200);
}
/* Just for demo */
div{
float: left;
margin: 10px;
transition: all 1s;
}
div:hover{
height: 200px;
width: 300px;
}
<svg width="0" height="0">
<defs>
<clipPath id="clip" clipPathUnits="objectBoundingBox">
<path d="M0 0, 0.9 0.1, 1 1, 0 1z" />
</clipPath>
</defs>
</svg>
<div>
Some text
</div>
<div id="image"></div>
Method 2: CSS Transforms
Generally it is better not to use transforms when there is going to be content like image or text inside the shape (or) when the shape's background is not going to be a solid color because then we would either have to (a) reverse transform the child elements separately to make them look normal or (b) use absolute positioning.
For this particular shape, having text inside the shape is not a problem even while using transforms but having non solid background colors would be.
Option 1: Using two pseudo-elements
You could use a couple of pseudo-elements with skew transforms, position one on the top and the other on the right to produce the required shape. Hover the shape in snippet to see how it is created.
div {
position: relative;
height: 150px;
width: 250px;
background: red;
margin: 40px 40px 0px 0px;
}
div:after,
div:before {
position: absolute;
content: '';
background: red;
z-index: -1;
backface-visibility: hidden;
}
div:before {
height: 12.5%;
width: 100%;
top: 0px;
left: 0px;
transform-origin: right top;
transform: skewY(3deg);
}
div:after {
height: 100%;
width: 12.5%;
right: -1px;
top: -1px;
transform-origin: right top;
transform: skewX(10deg);
}
/* Just for demo */
div{
transition: all 1s;
}
div:hover{
height: 250px;
width: 300px;
}
div:hover:after{
background: blue;
}
div:hover:before{
background: green;
}
<div>Some text</div>
Pros:
Shape can be created with a single element and can have text inside it without any trouble.
Cons:
Having gradients (or) images as background for the shape is complex because they would need reverse rotation as mentioned earlier.
Shape is not 100% scalable as dimensions of the container should change proportionately for the shape to be maintained (hover on the shape in the snippet to see what I mean). Reason is same as mentioned here.
Option 2: Using one pseudo-element
This is pretty similar to the previous option except that this uses a single pseudo-element along with a overflow: hidden on the parent.
div {
position: relative;
box-sizing: border-box;
height: 200px;
width: 300px;
padding: 10px;
overflow: hidden;
}
div:after {
position: absolute;
content: '';
top: 0px;
left: -20px;
height: 100%;
width: 100%;
background: red;
transform-origin: left bottom;
transform: skewY(5deg) skewX(7.5deg);
z-index: -1;
}
div:hover {
height: 300px;
width: 500px;
transition: all 1s;
}
<div>Some text</div>
Pros:
Shape can be created with a single element and can have text inside it without any trouble.
Shape is responsive and can adapt even if the container's dimensions change .
Cons:
Same constraint as the previous option for gradient and image backgrounds.
Not suitable if the overflow: hidden on the parent is a constraint.
A solution is:
div {
width: 300px;
height: 100px;
margin:50px;
background-color: yellow;
border: 1px solid black;
}
.thisdiv {
-ms-transform: skewX(-20deg); /* IE 9 */
-webkit-transform: skewX(-20deg); /* Safari */
transform: skewX(-20deg); /* Standard syntax */
}
<div class="thisdiv">
This is the div I will skew
</div>
This is how to skew an element, if you want to make the shape you added, try using two overlaping div's, position, scale, rotate and skew, like this:
.outer-div{
position:relative;
margin:50px;
width:200px;
height:200px;
border:2px black dashed;
}
.inner-one{
position:absolute;
left:0;
bottom:0;
width:180px;
height:180px;
background:red;
}
.inner-two{
position:absolute;
bottom:2px;
right:0px;
width:200px;
height:195px;
background:red;
transform: rotate(7deg) skew(14deg) scale(0.905); /* Standard syntax */
}
<div class="outer-div">
<div class="inner-one">
</div>
<div class="inner-two">
</div>
</div>
2 Triangle Solution for Irregular Quadrilateral in CSS
In looking at your image, I notice that the skew at the top and right are really just long, narrow triangles overlaying the rectangle.
So what I did was create triangles using CSS border properties and absolutely position them over the rectangle.
#rectangle {
width: 400px;
height: 200px;
background-color: red;
margin-top: 25px;
position: relative;
}
#triangle-down {
border-left: 30px solid red;
border-right: 0;
border-top: 200px solid transparent;
position: absolute;
right: -30px;
top: 0;
}
#triangle-left {
border-top: 0;
border-bottom: 15px solid red;
border-right: 400px solid transparent;
position: absolute;
right: 0;
top: -15px;
}
<div id="rectangle">
<div id="triangle-down"></div>
<div id="triangle-left"></div>
</div>
jsFiddle demo
You could check out the clip-path property (see below from MDN), but support is very patchy. Chrome 24+ supports with prefix and FF, but only URL values, which reference a path in an SVG. You can read more about clip-path here.
Here's a basic pen - this will only work in Chrome.
From MDN
The clip-path CSS property prevents a portion of an element from getting displayed by defining a clipping region to be displayed i.e, only a specific region of the element is displayed. The clipping region is a path specified as a URL referencing an inline or external SVG, or shape method such as circle(). The clip-path property replaces the now deprecated clip property.
developer.mozilla.org/en-US/docs/Web/CSS/clip-path (sorry, not enough rep to link)

Resources