I'm looking for a way to create bent top and bottom borders like the div in this image. I've tried some ways mentioned here but it depends on using white divs with border-radius on top of the main div but as you can see in this image it should be transparent to display the background image.
This is possible using svg.
For responsiveness remove the svg's width and height attributes, add viewBox="0 0 400 150" then try changing #image's width and height, the svg will respond to its width and height.
Demo on Fiddle demonstrating responsive shape.
Browser support for this approach - This will work on all browsers but IE8.
body {
background: teal;
}
#image {
width: 600px;
height: 300px;
position: relative;
background: url(http://lorempixel.com/600/300);
}
svg {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div id="image">
<svg width="400" height="150">
<path opacity="0.6" fill="red" d="M0,10 Q0,0 10,0 Q195,40 390,0 Q400,0 400,10 Q390,75 400,140 Q400,150 390,150 Q195,100 10,150 Q0,150 0,140 Q10,75 0,10" />
</svg>
</div>
Another posibility, not using clipping but multiple backgrounds.
Technically less advanced than chipChocolate answer, just providing an alternative
.test {
position: absolute;
left: 50px;
top: 50px;
width: 400px;
height: 100px;
border-radius: 10px;
background-image: radial-gradient(circle at center -778px,
transparent 800px, rgba(255,0,0,0.4) 800px),
radial-gradient(circle at center 828px,
transparent 800px, rgba(255,0,0,0.4) 800px);
background-position: center top, center bottom;
background-size: 100% 50%, 100% 50%;
background-repeat: no-repeat;
}
Thw idea is to divide the element in 2 halves, and then set in each a radial gradient that matches the corners position. The final posiotion of the gradients adjusted by hand.
Can de done responsively also.
demo
body {
width: 100%;
height: 100%;
background: url(http://placekitten.com/g/600/300);
}
.test {
position: absolute;
left: 50px;
top: 50px;
width: 400px;
height: 100px;
border-radius: 10px;
background-image: radial-gradient(circle at center -778px,
transparent 800px, rgba(255,0,0,0.4) 801px),
radial-gradient(circle at center 828px,
transparent 800px, rgba(255,0,0,0.4) 801px);
background-position: center top, center bottom;
background-size: 100% 50%, 100% 50%;
background-repeat: no-repeat;
}
<div class="test"></div>
An other approach with one div, 2 pseudo elements , border-radius and box-shadows :
div {
width: 70%; height: 150px;
margin: 20px auto;
position: relative;
border-radius: 10px;
overflow: hidden;
opacity: 0.5;
}
div:before,div:after {
content: '';
position: absolute;
height: 100%; width: 300%;
left: -100%;
border-radius: 100%;
box-shadow: 0px 0px 0px 140px red;
}
div:before {top: -146px;}
div:after {bottom: -146px;}
body {background: url('http://lorempixel.com/output/people-q-c-640-480-1.jpg');background-size: cover;}
<div></div>
Actually doing this using the CSS would almost be impossible, and you would be good if you just try out a simple PNG image, created using Photoshop, Google Images etc, and create the image exactly of this size and then use it inside the website.
You can add the transparency to the image while creating it by using the Adobe UI tools for editing the image, or you can use the alpha filter in CSS to set the transparency effect to it to display the element that is residing behind it (the effect that you want).
Related
http://lucasdebelder.be/stack/index.html
Make sure to check it out at 1680px width, then it's perfectly aligned together but if I make my screen bigger or smaller in width it doesn't align anymore any idea how I can get around this issue?
I'm trying to recreate my Dribbble shot.
Snippet of code.
.wrapper {
position: absolute;
top: 50%;
left: 50%;
height: 80%;
width: 80%;
transform: translate(-50%,-50%);
background: #F1F1F1;
box-shadow: 0 0 90px 0 rgba(0,0,0,0.45);
border-radius: 15px;
background-image: url("http://svgur.com/i/3W7.svg");
background-position: 129% 38%;
background-repeat: no-repeat;
background-size: 752px;
}
#section0 {
background-image: url("http://svgur.com/i/3W7.svg");
background-position: 100% 0%;
background-repeat: no-repeat;
background-size: 750px;
}
<section class="wrapper">
<h1>TEST</h1>
</section>
EDIT: It's hard to recreate this in a small jsfiddle, keep that in mind but then you get to see the code.
Your code snippet seems to be a little bit broken, but I was able to produce the desired effect by using the unit vw for your background position, which is dependant on the viewport width.
#section0 {
background-image: url(../img/1/bol.svg), url(../img/1/vlekBG.svg);
background-position: 0vw bottom, 61vw;
background-repeat: no-repeat;
background-size: auto, 750px;
}
.wrapper {
position: absolute;
top: 50%;
left: 50%;
height: 80%;
width: 80%;
transform: translate(-50%,-50%);
background: #F1F1F1;
box-shadow: 0 0 90px 0 rgba(0,0,0,0.45);
border-radius: 15px;
background-image: url(../img/1/vlekBG.svg);
background-position: 51vw;
background-repeat: no-repeat;
background-size: 752px;
These are the changes I made in the developer tools and the imaged stayed aligned, independet of the viewport width.
Edit: changed the code a little, because I didn't realize there were two background images in #section0
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
body{
background-color: #000;
height: 100vh;
}
section {
width: 100%;
height: 100%;
}
#section1 {
background-color: #f0f0f0;
}
#bubbles1, #bubbles2{
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: -1;
}
#bubbles1{
background: url('img/greencat.png') 60% 50% no-repeat fixed;
background-color: #f0f0f0;
}
#bubbles2{
background: url('img/catb.png') 60% 50% no-repeat fixed;
position: fixed;
-webkit-backface-visibility: hidden;
}
#fish{
background: transparent url('img/textgreen.png') no-repeat bottom left fixed;
height: 100%;
width: 100%;
position: absolute;
top: 0px;
}
#fish1{
background: transparent url('img/textblue.png') no-repeat bottom left fixed;
height: 100%;
width: 100%;
/* position: absolute;*/
top: 0px;
}
#media screen and (max-width: 860px){
ound-image: url('img/greencat-mobile.png');
background-size: 250vw 100vh;
background-position: 53% 50%;
}
#bubbles2{
background-image: url('img/catb-mobile.png');
background-size: 250vw 100vh;
background-position: 53% 50%;
position: fixed;
-webkit-backface-visibility: hidden;
}
#fish{
background: transparent url('http://www.intomorrow.com/wp-content/uploads/2016/06/Barnsley-House-Spa-2-844x800.jpg') no-repeat 3% 78% fixed;
position: absolute;
}
#fish1{
background: transparent url('http://www.intomorrow.com/wp-content/uploads/2016/08/Fairmont-Pittsburgh-30-844x800.jpg') no-repeat 3% 78% fixed;
}
}
<section id="section1">
<div id="bubbles1"></div>
<div id="fish"></div>
</section>
<section id="section2">
<div id="bubbles2"></div>
<div id="fish1"></div>
</section>
This is my html and css, the problem is when i scroll on mobile devices than image is flikering, not stick to the fixed position. I gave the position fixed in css but it is not working. I checked on Android, Windows and Apple devices.
Android : first image moved up on scrolling
Windows : first image displaying proper but when i scroll for second image than its flikering
Apple : display white background insted of image, second image visible but its flikering on scroll
Most mobile devices have a delay in updating the background position after scrolling a page with fixed backgrounds.
i came across this problem too.
i know 3 possible fixes for this
1. you can try using a pseudo-element and add background fixed to it
2. you can make another div inside the fixed div. and add background to that div
3. use -webkit-transform: translateZ(0x); transform:translateZ(0) to force hardware acceleration
see more here
http://caniuse.com/#search=background-attachment
Background size on iOS
let me know if it helps
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)
How could I achieve a background that looked similar to this image:
Only 3 colors, angled from the top corner out like a sunray.
Maybe sticking with a simple PNG or SVG background image would be a better approach.
The effect can be achieved with CSS using pseudo-elements and transforms and the below is a sample snippet. But I don't think using CSS is the correct option for this. It would be better to use a PNG image.
The snippet uses a couple of pseudo-elements with different background colors skewed at required angles to produce the three-color effect.
.bg {
position: relative;
height: 200px;
width: 400px;
padding: 4px;
background: orange;
overflow: hidden;
}
.bg:after,
.bg:before {
position: absolute;
content: '';
left: 0px;
height: 100%;
width: 100%;
transform-origin: right top;
}
.bg:before {
top: 0px;
background: red;
transform: skewY(-45deg);
}
.bg:after {
top: -100%;
background: yellow;
transform: skewY(-15deg);
}
span {
position: relative;
z-index: 2;
}
/* Just for demo */
.bg:hover {
height: 200px;
width: 500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="bg">
<span>Some content inside</span>
</div>
Angled linear-gradients also could be used but I don't think they are good for dynamic sized container elements as the angles need to be modified as the dimensions change to keep the appearance the same.
Below is a snippet using linear-gradient. Hover on the shape to see how a change of width and/or height affects it.
.bg {
position: relative;
height: 200px;
width: 400px;
background: linear-gradient(310deg, red 30%, transparent 30%), linear-gradient(340deg, transparent 58%, yellow 58%), orange;
overflow: hidden;
}
.bg:hover {
height: 200px;
width: 500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="bg">
<span>Some content inside</span>
</div>
SVG
This can be done with SVG.
I used three polygon shapes. This can be set to a background-image.
Or alternatively can be used inline so you can use css properties on it.
html, body {
margin: 0;
padding: 0;
}
.triple {
width: 250px;
height: 250px;
}
.triple:hover {
width: 500px;
height: 100px;
}
<svg class="triple" viewBox="0 0 100 100" preserveAspectRatio="none">
<polygon fill="#dd2" points="0,0 100,0 0,60" />
<polygon fill="#bb2" points="0,60 100,0 30,100 0,100 " />
<polygon fill="#992" points="30,100 100,0 100,100" />
</svg>
Yes, it can be done with gradients, in a responsive way.
That is asuming that when the aspect ratio changes, you don't want to keep the angles, but the relative positions
The trick is to use simbolic names in the gradient direction, and then playing with the size and the position of the background-image
.test {
display: inline-block;
border: solid 1px black;
background-image: linear-gradient(to top left, tomato 50%, transparent 50%),
linear-gradient(to bottom right, lightgreen 50%, transparent 50%);
background-size: 60% 100%, 100% 50%;
background-repeat: no-repeat;
background-position: bottom right, top left;
}
#test1 {
width: 200px;
height: 100px;
}
#test2 {
width: 100px;
height: 100px;
}
#test3 {
width: 70px;
height: 100px;
}
<div class="test" id="test1"></div>
<div class="test" id="test2"></div>
<div class="test" id="test3"></div>
Use a 4-color GIF image. This will give you both cross-browser/platform compatibility as well as backward compatibility, and the size will be small with this type of image. If the colors are subtle as shown the "jaggies" will be camouflaged somewhat (or provide a larger size).
A good option is to use SVG which has good support in modern up-to-date browsers.