The following snippet perfectly works on Chrome: the background image fades into to the background behind towards the bottom.
div {
width: 200px;
height: 200px;
background-image: url("http://i.imgur.com/wcDxIZG.jpg");
background-size: cover;
background-position: center center;
-webkit-mask-image: linear-gradient(black, black, transparent);
mask-image: linear-gradient(black, black, transparent);
}
<div></div>
But it doesn't work on Firefox, the value is said to be incorrect.
Why ? And how can I fix that ?
Note that I know how to use another div as overlay, which isn't a general solution to me as it has too many consequences on content and element position. The only answers I'm interested in are the ones which fix the background of the div.
I don't know why, but you can replicate the effect by using the :after property for this, and this works for all browsers - even our old friend IE:
.container {
height: 200px;
overflow: hidden;
position: relative;
}
.image {
width: 200px;
height: 200px;
background-image: url("http://i.imgur.com/wcDxIZG.jpg");
background-size: cover;
background-position: center center;
}
.image:after {
content: '';
filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FAFAFA', endColorstr='#FAFAFA');
background-image: -webkit-linear-gradient(top, rgba(248, 244, 243, 0) 0%, #fafafa 100%);
background-image: -ms-linear-gradient(top, rgba(248, 244, 243, 0) 0%, #fafafa 100%);
background-image: linear-gradient(to bottom, rgba(2248, 244, 243, 0) 0%, #fafafa 100%);
display: block;
position: absolute;
pointer-event: none;
bottom: 0;
left: 0;
width: 200px;
height: 20%;
}
<div class="container">
<div class="image"></div>
</div>
Starting from Firefox 53 (released April 19, 2017) , this is now possible as the support of masking images has been completed.
See http://caniuse.com/#search=mask
Related
Essentially, I want to create an element that combines a "to right" gradient with a color stop at a certain percentage and another color stop for the remaining width with a "to bottom" gradient that fades both colors to transparent. Getting the color stop part is easy, getting the fade is easy; I just can't figure out how to get both.
/*I can get this:*/
div {
width: 500px;
height: 100px;
}
.color-change {
background: linear-gradient(to right, rgb(255, 175,157) 80%, rgb(255, 95, 89) 80%);
}
/*or this:*/
.fade {
background:linear-gradient(to bottom, rgba(252, 193, 176, 0), #fcc1b0);
/* but not both*/
<div class="color-change"></div>
<div class="fade"></div>
This probably isn't hard but I can't find any examples that do exactly this. I could just use a png., but it seems as though this ought to be doable in CSS. Thanks for any suggestions (or better, solutions).
Use CSS ::before (:before)
In CSS, ::before creates a pseudo-element that is the first child of
the selected element. It is often used to add cosmetic content to an
element with the content property. It is inline by default. https://developer.mozilla.org
div {
width: 500px;
height: 100px;
}
.fade {
background: linear-gradient(to bottom, rgba(252, 193, 176, 0), #fcc1b0);
position: relative;
}
.fade::before {
display: inline-block;
content: "";
height: 100%;
width: 20%;
background: black;
position: absolute;
right: 0;
background: linear-gradient(0deg, rgba(246,115,115,1) 4%, rgba(250,192,194,1) 34%, rgba(255,233,234,1) 66%, rgba(255,255,255,1) 100%);
}
<div class="fade"></div>
Multiple background layer can do it:
.color-change {
--p:80%; /* this is your percentage */
background:
linear-gradient(to bottom, transparent, #fcc1b0) left,
linear-gradient(to bottom, transparent, rgb(255, 95, 89)) right;
background-repeat:no-repeat;
background-size:var(--p) 100%,calc(100% - var(--p)) 100%;
width: 500px;
height: 100px;
margin:10px;
}
<div class="color-change"></div>
<div class="color-change" style="--p:50%"></div>
<div class="color-change" style="--p:20%"></div>
Or you can mask it with a pseudo element. This is real transparent.
body {
background: dodgerblue;
}
div {
width: 500px;
height: 100px;
}
.color-change {
-webkit-mask: linear-gradient(to bottom, transparent, #000);
mask: linear-gradient(to bottom, transparent, #000);
position: relative;
}
.color-change:before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: linear-gradient(to right, rgb(255, 175, 157) 80%, rgb(255, 95, 89) 80%);
}
<div class="color-change"></div>
According to this answer, this should work:
#shop {
background-image: url('../images/tilecovers/shop.jpg'),
linear-gradient(
135deg,
rgba(228,245,252,0.18) 0%,
rgba(191,232,249,0.2) 49%,
rgba(191,232,249,0.21) 65%,
rgba(159,216,239,0.21) 73%,
rgba(82,189,236,0.22) 100%);
}
It doesn't work though, only the image is visible.
After a few refreshes, I noticed the gradient is loading first, then the image on top of it. How can I make the translucent gradient on top of the background image?
Not sure about cross browser support but one option is using the background-blend-mode property like so:
.shop {
background-image: url('https://placeholdit.co//i/500x250?bg=111111'),
linear-gradient(
135deg,
rgba(228,245,252,0.18) 0%,
rgba(191,232,249,0.2) 49%,
rgba(191,232,249,0.21) 65%,
rgba(159,216,239,0.21) 73%,
rgba(82,189,236,0.22) 100%);
background-blend-mode: overlay;
width: 500px;
height: 250px;
}
.shop-no-gradient {
background-image: url('https://placeholdit.co//i/500x250?bg=111111');
width: 500px;
height: 250px;
}
<div class="shop"></div>
<br>
<div class="shop-no-gradient"></div>
Use :before to apply the filter.
Like so:
#shop {
width: 350px;
height: 150px;
background: url("http://via.placeholder.com/350x150") center center no-repeat;
}
#shop:before {
width: 350px;
height: 150px;
content: '';
position: absolute;
background-image: linear-gradient(
135deg,
rgba(228,245,252,0.18) 0%,
rgba(191,232,249,0.2) 49%,
rgba(191,232,249,0.21) 65%,
rgba(159,216,239,0.21) 73%,
rgba(82,189,236,0.22) 100%
);
}
<div id="shop">
</div>
I would like to make some background shapes on my website ...
this is the look that I want
I have tried using the method with rotated/skewed rectangles, it works perfect just when I have only one color on the section below (because I can use the same color for the shapes). If I want to use a texture like in the image attached I will end up having this depending on what method I use. I have also tried using a svg for making the shapes, but I'm not sure if it's the best solution. I'm wondering if there is a clever way to do this. I realize maybe I'm not as clear as a should be, but thank you for finding time to read this.
You'll probably want to experiment with SVGs and masks, depending upon how complicated your shapes are going to be. You can find some great guidance here: https://www.sitepoint.com/masking-in-the-browser-with-css-and-svg/.
Illustrator can be saved as an SVG, but if you're using Sketch it's even easier! You'll notice the code outputs individual coordinates.
You can see a decent demo here: http://cssplant.com/clip-path-generator
This a concept. Try self to work project.
* {
margin: 0;
padding: 0;
}
.wrapper {
width: 100vw;
padding-top: 50%;
position: relative;
background-image: linear-gradient(90deg, rgba(0, 0, 0, .5) 66.6666667%, rgba(255, 255, 0, .6) 66.6666667%), url(http://beerhold.it/1200/600);
background-repeat: no-repeat;
background-size: cover;
overflow: hidden;
}
.wrapper:nth-child(2) {
background-image: linear-gradient(90deg, rgba(255, 255, 255, .7) 0, rgba(255, 255, 255, .7) 100%), url(http://beerhold.it/1400/700);
}
.topleft,
.topright,
.bottomleft,
.bottomright {
position: absolute;
top: 0;
height: 100%;
}
.topleft {
left: 0;
top: 40%;
width: 66.66666667%;
background-image: linear-gradient(transparent 0, transparent 50%, #fff 50%, #fff);
transform: skewY(7deg);
}
.topright {
left: 66.66666667%;
width: 33.33333334%;
top: 42.3%;
background-image: linear-gradient(transparent 0, transparent 50%, #fff 50%, #fff);
transform: skewY(-10deg);
}
.bottomleft {
left: 0;
top: -94%;
width: 33.33333334%;
background-image: linear-gradient(180deg, transparent 0, transparent 50%, #fff 50%, #fff );
transform: skewY(-10deg);
}
.bottomright {
left: 33.33333334%;
width: 66.66666667%;
top: -92%;
background-image: linear-gradient(180deg, transparent 0, transparent 50%, #fff 50%, #fff);
transform: skewY(7deg);
}
<div class="wrapper">
<div class="topleft"></div>
<div class="topright"></div>
</div>
<div class="wrapper">
<div class="topleft"></div>
<div class="topright"></div>
<div class="bottomleft"></div>
<div class="bottomright"></div>
</div>
When i create background gradient like this:
background: radial-gradient(ellipse at center, #ffffff 0%,#ffffff 59%,#ededed 100%);
I get ellipse that is inside the div, and conform to shape of div. So if div is large in height then ellipse would be stretched vertically. If div is a square then ellipse would be like a circle. That's fine, i want to control height of ellipse.
The exact question can be addressed by combining the last 2 answers: circle gradient and adjusting the background size.
Something like this:
div {
width: 300px;
height: 100px;
background: radial-gradient(circle, white 0%, red 50%, black 100%);
background-size: 100% 200%;
background-position: 0% 50%;
}
<div></div>
I find it less of a hassle than nested divs, and by playing with the background-position and size values, you can get some pretty cool effects!
Use a div with overflow set to hidden, and a div inside of it absolutely positioned with a fixed height.
#outer {
height: 100px;
overflow: hidden;
position: relative;
width: 200px;
}
#inner {
background: radial-gradient(ellipse at center, #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%);
bottom: 0;
height: 150px;
position: absolute;
width: 200px;
}
<div id="outer">
<div id="inner"></div>
</div>
You can play with the background dimensions and position:
div {
width: 300px;
height: 100px;
background: radial-gradient(ellipse at center, white 0%, red 100%);
background-size: 100% 200%;
background-position: 0% 50%;
}
demo
You can try circle instead of ellipse:
Demo on dabblet
.rect2 {
width: 600px;
height: 100px;
line-height: 100px;
text-align: center;
background: radial-gradient(circle, #ffffff 0%, #ffffff 59%, #dcdcdc 100%);
}
Example: http://cdpn.io/EaDdx
Next to the "Sample Title" you can see the arrowhead I'm trying to create. I'm trying to get this to work in the same manner as the rectangles and the circle, allowing it to act as a 'porthole' to it's own fixed background image.
I've tried everything from using borders to create a triangle (which blocked out the body's background image), to using various rotations, alternations of use between an actual background image and background gradient.
Right now I'm using basically using this method, as so:
.gradient-triangle {
width: 50px;
height: 50px;
position: absolute;
top: 0px;
left: -25px;
clip: rect(auto 25px 50px auto);
}
.gradient-triangle:after {
content: '';
position: absolute;
top: 4px;
bottom: 4px;
left: 9px;
right: 0px;
-webkit-transform:rotate(-45deg);
background-attachment: fixed;
background: -moz-linear-gradient(45deg, #000000 0%, #000000 50%, #ffffff 50%, #ffffff 100%);
background: -webkit-gradient(linear, left bottom, right top, color-stop(0%,#000000), color-stop(49%,#000000), color-stop(50%,#ffffff), color-stop(100%,#ffffff));
background: -webkit-linear-gradient(45deg, #000000 0%,#000000 49%,#ffffff 50%,#ffffff 100%);
background: -o-linear-gradient(45deg, #000000 0%,#000000 50%,#ffffff 50%,#ffffff 100%);
background: -ms-linear-gradient(45deg, #000000 0%,#000000 50%,#ffffff 50%,#ffffff 100%);
background: linear-gradient(45deg, #000000 0%,#000000 50%,#ffffff 50%,#ffffff 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#ffffff',GradientType=1 );
background-position: center center;
background-attachment: fixed;
border: 1px solid #fff;
}
This is mainly a chrome issue right now, though as you'll see, it does something different in each browser, which is pretty odd.
I haven't seen any other websites that do this sort of thing, using fixed background images, within elements, to offer the "porthole" style view. I'd be interested to see any that anyone may know of, to checkout how they handle things similar to this.
Edit: Just to clarify what I think is causing this. Usually a fixed background image is relative to the window, not the element it's assigned to. As soon as that element is rotated, the background image becomes relative to it. There's a good chance this is a browser bug, I'd just like to be sure.
I could get the following to work in Chrome:
CSS
.filler {
height: 2000px;
}
.test2 {
position: absolute;
width: 400px;
height: 370px;
left: 219px;
top: 10px;
background-attachment: fixed;
background-repeat: no-repeat;
background-position-x: -266px;
background-position-y: -107px;
}
.container {
-webkit-transform: rotate(45deg);
position: absolute;
margin-left: -275px;
margin-top: -116px;
clip: rect(-265px, 693px, 0px, 428px);
}
.container2 {
-webkit-transform: rotate(-45deg);
position: absolute;
}
.test {
position: absolute;
width: 186px;
height: 400px;
left: 300px;
top: 85px;
background-attachment: fixed;
background-repeat: no-repeat;
}
.test, .test2 {
background-image: url(http://placekitten.com/900/600);
}
fiddle
There is alot of hand-set positions; probably that could be set easier playing with transform-origins.
Also, I have a difference between positions in Chrome (on one side) and Firefox - IE (on the other). Still trying to understand why ..