Imitate Photoshop blend effects like multiply, overlay etc - css
I'm making a website with a full page background image. I want to create a background image for a side column that acts like a Photoshop layer with multiply as blend mode. It's just a blue colored surface with the 'behaviour' of a Photoshop multiply layer.
It's not possible to merge the overlay and the image since the background can change when the website is opened in another screen ratio/size.
There are a lot of solutions on SO, but they only work with multiplying 2 images with a fixed position, not a colored surface with variable position/background.
Are there tricks to achieve this?
jsBin demo
Use the CSS3 property mix-blend-mode MDN Docs
(For fallback use an rgba or hsla color with a bit of alpha transparency.)
Assign a desired blend-* class to your element like:
/* ::: BLEND MODE CLASSES */
.blend-normal{ mix-blend-mode: normal; }
.blend-multiply{ mix-blend-mode: multiply; }
.blend-screen{ mix-blend-mode: screen; }
.blend-overlay{ mix-blend-mode: overlay; }
.blend-darken{ mix-blend-mode: darken; }
.blend-lighten{ mix-blend-mode: lighten; }
.blend-colordodge{ mix-blend-mode: color-dodge; }
.blend-colorburn{ mix-blend-mode: color-burn; }
.blend-hardlight{ mix-blend-mode: hard-light; }
.blend-softlight{ mix-blend-mode: soft-light; }
.blend-difference{ mix-blend-mode: difference; }
.blend-exclusion{ mix-blend-mode: exclusion; }
.blend-hue{ mix-blend-mode: hue; }
.blend-saturation{ mix-blend-mode: saturation; }
.blend-color{ mix-blend-mode: color; }
.blend-luminosity{ mix-blend-mode: luminosity; }
/* ::: SET HERE YOUR INITIAL COLORS */
div{
background: rgba(0, 80, 200, 0.8);
color: #fff;
}
div span{
color:#000;
}
/* ::: FOR DEMO ONLY */
html, body{margin:0; height:100%;font:100%/1 sans-serif;}
body{background: url(http://i.stack.imgur.com/cBy6q.jpg)fixed 50%/cover;}
div{font-size:2.2em; padding:20px; margin:15px;}
div:first-of-type{margin-top:150px;}
div:last-of-type{margin-bottom:150px;}
<div class="">(rgba) <span>(rgba)</span></div>
<div class="blend-normal">normal <span>normal</span></div>
<div class="blend-multiply">multiply <span>multiply</span></div>
<div class="blend-screen">screen <span>screen</span></div>
<div class="blend-overlay">overlay <span>overlay</span></div>
<div class="blend-darken">darken <span>darken</span></div>
<div class="blend-lighten">lighten <span>lighten</span></div>
<div class="blend-colordodge">color-dodge <span>color-dodge</span></div>
<div class="blend-colorburn">color-burn <span>color-burn</span></div>
<div class="blend-hardlight">hard-light <span>hard-light</span></div>
<div class="blend-softlight">soft-light <span>soft-light</span></div>
<div class="blend-difference">difference <span>difference</span></div>
<div class="blend-exclusion">exclusion <span>exclusion</span></div>
<div class="blend-hue">hue <span>hue</span></div>
<div class="blend-saturation">saturation <span>saturation</span></div>
<div class="blend-color">color <span>color</span></div>
<div class="blend-luminosity">luminosity <span>luminosity</span></div>
Simple with a bit of SVG:
<svg width="200" height="200" viewBox="10 10 280 280">
<filter id="multiply">
<feBlend mode="multiply"/>
</filter>
<image id="kitten" x="0" y="0" width="300" height="300" xlink:href="http://placekitten.com/300" />
</svg>
and some CSS:
#kitten:hover {
filter:url(#multiply);
}
The fiddle: http://jsfiddle.net/7uCQQ/
As FC said you can use CSS3 custom filters or SVG/Canvas.
But if you need a cross-browser solution for blending layers you have to use JS method. For example, JS image processing script from Pixastic: http://www.pixastic.com/lib/docs/actions/blend/
In addition it has a lot of other visual effects like blur, noise, crop, mosaic etc.
I used this script before for several projects, it works realy great :)
Hope it helps you)
I'm a designer and had the same problem, looking for solutions before putting the psd over to the dev team - you can try this js and/or http://css-tricks.com/basics-css-blend-modes/
Jsfiddle code:
#kitten:hover {
filter:url(#multiply);
}
<svg width="200" height="200" viewBox="10 10 280 280">
<filter id="multiply">
<feBlend mode="multiply"/>
</filter>
<image id="kitten" x="0" y="0" width="300" height="300" xlink:href="http://placekitten.com/300" />
</svg>
Hope it works for you or others here. :)
Related
CSS: How to create a background-image masked by a mask-image
I have a div that I want to give a regular background-image modified by a mask-image, so that the page background, which uses background-attachment: fixed; can "float" as if seen through a window, behind the div. For the mask image, I want to be able to use either PNG or SVG. Even if I use an SVG, I would rather not use the mask:url(mask.svg#element); method because the SVG artwork may not be simple clipping masks, but also include shades of gray in the form of blurs, gradients, etc. I would like the mask to use the standard white = opaque / black = transparent schema. I believe mask-mode: alpha; is correct for this configuration? Here's what I've managed to get working so far. The trouble is that it relies on an SVG id (instead of a whole image), and also the size is way smaller than the div, for some reason. <!DOCTYPE html> <html> <head> <style> body { color: #174; background-color: #def; font-family: sans-serif; } .masked-bg { width: 600px; height: 600px; background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAL0lEQVQIW22KQQ4AMAjC4P+PZlXnzZoYwVpypFjACsHmCtPlZwxAaCqf5XzWWPsB9TsMBL7veUEAAAAASUVORK5CYII=); background-repeat: repeat; background-attachment: fixed; background-size: 10px; image-rendering: pixelated; mask-image: url(#svgmask); mask-repeat: no-repeat; mask-size: contain; mask-position: center; mask-origin: content-box; } </style> </head> <body> <h1>mask-image</h1> <p>with a fixed background</p> <div class="masked-bg"></div> <svg width="0" height="0"> <!-- sized to 0 because this SVG data is only to be used in the div background --> <mask id="svgmask"> <polygon fill="#ffffff" points="100,10 40,198 190,78 10,78 160,198"></polygon> <text x="0" y="36" fill="white" transform="rotate(30 20,40)" font-family="sans-serif">V e c t o r</text> </mask> </svg> </body> </html>
How to make an element of such a complex shape? [duplicate]
So I'm working on a site and I was wondering if it's possible to, purely using HTML5, CSS3 (and JavaScript if needed), make a div with a curved bottom, so it will look practically like this: Or can this only be done using a background image? <body> <div class="navbar navbar-fixed-top"> <div class="navbar-inner"> <ul class="nav"> <li>Home</li> </ul> </div> </div> </body>
There are different approaches that can be adopted to create this shape. Below is a detailed description of possibilities: SVG Based Approaches: SVG is the recommended way to create such shapes. It offers simplicity and scale-ability. Below are a couple of possible ways: 1- Using Path Element: We can use SVG's path element to create this shape and fill it with some solid color, gradient or a pattern. Only one attribute d is used to define shapes in path element. This attribute itself contains a number of short commands and few parameters that are necessary for those commands to work. Below is the necessary code to create this shape: <path d="M 0,0 L 0,40 Q 250,80 500,40 L 500,0 Z" /> Below is a brief description of path commands used in above code: M command is used to define the starting point. It appears at the beginning and specify the point from where drawing should start. L command is used to draw straight lines. Q command is used to draw curves. Z command is used to close the current path. Output Image: Working Demo: svg { width: 100%; } <svg width="500" height="80" viewBox="0 0 500 80" preserveAspectRatio="none"> <path d="M0,0 L0,40 Q250,80 500,40 L500,0 Z" fill="black" /> </svg> 2- Clipping: Clipping means removing or hiding some parts of an element. In this approach, we define a clipping region by using SVG's clipPath element and apply this to a rectangular element. Any area that is outside the clipping region will be hidden. Below is the necessary code: <defs> <clipPath id="shape"> <path d="M0,0 L0,40 Q250,80 500,40 L500,0 Z" /> </clipPath> </defs> <rect x="0" y="0" width="500" height="80" fill="#000" clip-path="url(#shape)" /> Below is brief description of the elements used in above code: defs element is used to define element / objects for later use in SVG document. clipPath element is used to define a clipping region. rect element is used to create rectangles. clip-path attribute is used to link the clipping path created earlier. Working Demo: svg { width: 100%; } <svg width="500" height="80" viewBox="0 0 500 80" preserveAspectRatio="none"> <defs> <clipPath id="shape"> <path d="M0,0 L0,40 Q250,80 500,40 L500,0 Z" /> </clipPath> </defs> <rect x="0" y="0" width="500" height="80" fill="#000" clip-path="url(#shape)" /> </svg> CSS Based Approaches: 1- Using Pseudo Element: We can use ::before or ::after pseudo element to create this shape. Steps to create this are given below: Create a layer with ::before OR ::after pseudo element having width and height more than its parent. Add border-radius to create the rounded shape. Add overflow: hidden on parent to hide the unnecessary part. Required HTML: All we need is a single div element possibly having some class like shape: <div class="shape"></div> Working Demo: .shape { position: relative; overflow: hidden; height: 80px; } .shape::before { border-radius: 100%; position: absolute; background: black; right: -200px; left: -200px; top: -200px; content: ''; bottom: 0; } <div class="shape"></div> 2- Radial Gradient: In this approach we will use CSS3's radial-gradient() function to draw this shape on the element as a background. However, this approach doesn't produce very sharp image and it might have some jagged corners. Required HTML: Only single div element with some class will be required i.e. <div class="shape"></div> Necessary CSS: .shape { background-image: radial-gradient(120% 120px at 50% -30px, #000 75%, transparent 75%); } Working Demo: .shape { background: radial-gradient(120% 120px at 50% -30px, #000 75%, transparent 75%) no-repeat; height: 80px; } <div class="shape"></div> JavaScript Based Approaches: Although not required in this case but for the sake of completeness, I'm adding this approach as well. This can be useful in some cases as well: HTML5 Canvas: We can draw this shape on HTML5 Canvas element using path functions: var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(0, 40); ctx.quadraticCurveTo(311, 80, 622, 40); ctx.lineTo(622, 0); ctx.fill(); <canvas id="canvas" width="622" height="80"></canvas> Below is a brief description of the methods used in above code: beginPath() is used to create a new path. Once a new path is created, future drawing commands are directed into the path. moveTo(x, y) moves the pen to the coordinates specified by x and y. lineTo(x, y) draws a straight line from the current pen position to the point specified by x and y. quadraticCurveTo(cp1x, cp1y, x, y) draws a curve from current pen position to the point specified by x and y using control point specified by cp1x and cp1y. fill() fills the current path using non-zero or even-odd winding rule. Useful Resources: Radial Gradient: Specs, MDN SVG: Specs, MDN HTML5 Canvas: Specs, MDN
CSS: div{ background-color:black; width:500px; height:50px; border-bottom-left-radius:50%; border-bottom-right-radius:50%; } see is this ok for you div { background-color: black; width: 500px; height: 50px; border-bottom-left-radius: 50%; border-bottom-right-radius: 50%; } <div> </div>
This is what you want: div{ background-color: black; width: 500px; height: 300px; border-radius: 0 0 50% 50% / 50px; } Unlike the accepted answer, this works even when the height of the div is increased. Demo: jsFiddle
Yes, you can do this in CSS - basically make your div wider than the page to fix the too-rounded edges, then left-positioned to compensate, with bottom border radius using both x & y values, and negative bottom margin to compensate for the gap: .round-bottom { border-bottom-left-radius: 50% 200px; // across half & up 200px at left edge border-bottom-right-radius: 50% 200px; // across half & up 200px at right edge width: 160%; overflow: hidden; // make larger, hide side bits margin-bottom: -50px; // apply negative margin to compensate for bottom gap position: relative; left:-30%; // re-position whole element so extra is on each side (you may need to add display:block;) } .round-bottom { border-bottom-left-radius: 50% 150px !important; border-bottom-right-radius: 50% 150px !important; position: relative; overflow: hidden; width: 160%; margin-bottom:-50px; left:-30%; background-color:#444; background-image: url('https://upload.wikimedia.org/wikipedia/commons/a/a2/Tropical_Forest_with_Monkeys_A10893.jpg'); background-position: center center; background-size: 42% auto; height:150px; } .container { width: 100%; height: height:100px; padding-bottom:50px; overflow:hidden;} <div class="container"><div class="round-bottom"></div></div>
Try this .navbar{ border-radius:50% 50% 0 0; -webkit-border-radius:50% 50% 0 0; background:#000; min-height:100px; } jsFiddle File
border-radius for masking child SVG
I have a div with an svg child: <div> <svg>...</svg> </div> I'm trying to get rounded corners using CSS. However, if I set border-radius on the div it doesn't mask the SVG. This kinda makes sense, but is there a simple alternative?
Maybe you can use this code below: .clip-circle { clip-path: circle(50px at center); } Hope this can help you.
You can put the border-radius on the SVG. svg { border-radius: 50px; } <div> <svg width="400" height="300"> <rect width="100%" height="100%" fill="green"/> </svg> </div>
How would I change my SVG color with media queries?
I need to change my logo color to black, instead of white, when the screen is small than 992px. Much easier than showing and hiding 2 different images, I think. I tried adding this in the .svg file style tags, but it seems to just use the white fill and doesn't get affected with screen resize. <style type="text/css"> .logo-color{fill:#FFFFFF;} #media (min-width: 992px) { .logo-color { fill:#000000; } } </style> <path class="logo-color"...etc.. Thanks for any help. Edit: I should state that I'm calling it with this, if it makes a difference: <img src="css/img/logo.svg" alt="Logo" width="150" style="width:150px;">
I imagine there are different approaches to this but here is one: As per the #media query, when the screen width shrinks to less than 992px, the logo will change from a black image on a white background to a white image on a black background. svg { width: 414px; height: 96px; fill: rgb(0,0,0); background-color: rgb(255,255,255); } #media only screen and (max-width:992px) { svg { fill: rgb(255,255,255); background-color: rgb(0,0,0); } } <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 413.1 96"> <path d="M0.7,81.8L0.7,81.8v-0.9c0.2-3.2,1.4-5,3.5-5.5h15.6c2.2,0.4,3.4,2.6,3.5,6.4h-2.8c-0.1-2.4-0.8-3.5-2.1-3.5 H5.7c-1.2,0-1.9,1.1-2.1,3.2c0.2,1.9,0.9,2.8,2.1,2.8h14.2c2.1,0.5,3.3,2.2,3.5,5.3v0.7c-0.2,3.3-1.4,5.2-3.5,5.7H4.2 c-2.2-0.4-3.4-2.6-3.5-6.4h2.8c0.1,2.4,0.8,3.5,2.1,3.5h12.7c1.2,0,1.9-1.1,2.1-3.2c-0.2-1.9-0.9-2.8-2.1-2.8H4.2 C2.1,86.6,1,84.8,0.7,81.8L0.7,81.8z M81.2,95.9h-2.8V78.2h-8.5v-2.8h19.8v2.8h-8.5V95.9L81.2,95.9z M157.5,75.4v17 c-0.5,2.4-2.8,3.5-7.1,3.5h-7.1c-4.3,0-6.6-1.2-7.1-3.5v-17h2.8V91c0,1.4,1.4,2.1,4.3,2.1h7.1c2.8,0,4.2-0.7,4.2-2.1V75.4H157.5 L157.5,75.4z M206.9,78.2v14.9h13.4c1.4,0,2.1-1.4,2.1-4.3v-6.4c0-2.8-0.7-4.2-2.1-4.2H206.9L206.9,78.2z M204,95.9V75.4h17.7 c2.4,0.5,3.5,2.8,3.5,7.1v6.4c0,4.3-1.2,6.6-3.5,7.1L204,95.9L204,95.9z M274.6,95.9h-2.8V75.4h2.8V95.9L274.6,95.9z M326.1,78.2 c-1.4,0-2.1,1.4-2.1,4.2v6.4c0,2.8,0.7,4.3,2.1,4.3h12.7c1.4,0,2.1-1.4,2.1-4.3v-6.4c0-2.8-0.7-4.2-2.1-4.2H326.1L326.1,78.2z M324.7,95.9c-2.4-0.5-3.5-2.8-3.5-7.1v-6.4c0-4.2,1.2-6.6,3.5-7.1h15.6c2.4,0.5,3.5,2.8,3.5,7.1v6.4c0,4.3-1.2,6.6-3.5,7.1H324.7 L324.7,95.9z M390.4,81.8L390.4,81.8v-0.9c0.2-3.2,1.4-5,3.5-5.5h15.6c2.2,0.4,3.4,2.6,3.5,6.4h-2.8c-0.1-2.4-0.8-3.5-2.1-3.5h-12.7 c-1.2,0-1.9,1.1-2.1,3.2c0.2,1.9,0.9,2.8,2.1,2.8h14.2c2.1,0.5,3.3,2.2,3.5,5.3v0.7c-0.2,3.3-1.4,5.2-3.5,5.7H394 c-2.2-0.4-3.4-2.6-3.5-6.4h2.8c0.1,2.4,0.8,3.5,2.1,3.5H408c1.2,0,1.9-1.1,2.1-3.2c-0.2-1.9-0.9-2.8-2.1-2.8h-14.2 C391.8,86.6,390.6,84.8,390.4,81.8z" /> <path d="M20.5,24.1h43.2c26.7,0,26.6,36.6,0,36.6H1.2v-11h59.6c9.8,0,9.7-13.8,1-13.8H19.9C-6.6,35.9-6.6,0,19.9,0 c57.7,0,114.6,0,172.2,0c6,0,10.3,0.9,13,2.8c2.7,1.8,4.1,4.8,4.1,9V26c0,4.1-1.3,7.2-4.1,9.1c-2.7,1.9-7,2.8-13,2.8h-9.9l34.9,22.9 h-25.2l-44.5-33.3h36.9c3,0,5.1-0.3,6.3-1.1c1.1-0.7,1.7-2,1.7-3.8v-7.3c0-1.8-0.5-3-1.7-3.7c-1.1-0.7-3.2-1.1-6.3-1.1 c-21.1,0-40.7,0.8-61.9,0.8v49.5h-17.6V11.3C76.7,11.3,49,11,20.7,11C13.7,11,13.8,24.1,20.5,24.1L20.5,24.1z M354,23.9l0.1-8 c0.1-7.2,5.5-5.3,10.7-5.6h46.8V0h-50.9h-6.9c-6,0-10.4,1-13.1,2.8c-2.7,1.9-4.1,4.9-4.1,9.1v11.6v14.2v11.6c0,4.1,1.4,7.2,4.1,9.1 c2.7,1.9,7,2.8,13.1,2.8l14-0.4h44.6V49.3l-51.6,1.2c-4.9-0.1-6.4-0.1-6.6-5.1c-0.1-1.5-0.2-9.7-0.2-11.2h57.3V23.9H354L354,23.9z M306.3,10.6c-19,0-37.9-0.1-56.8-0.1V0h64.6c6,0,10.4,1,13.1,2.8c2.7,1.9,4.1,4.9,4.1,9.1v13.5c0,4.1-1.4,7.1-4.1,9 s-7,2.8-13.1,2.8h-47.3v23.6h-17.3V26.5c19,0,37.8,0.2,56.8,0.2c3,0,5.1-0.4,6.2-1.1s1.7-2,1.7-3.7v-6.5c0-1.8-0.6-3-1.7-3.7 C311.4,10.9,309.3,10.6,306.3,10.6L306.3,10.6z M224,60.7V0h17.6v60.7H224z" /> </svg>
Embed svg code in html instead add it as image and it will work
CSS how to warp/bend an image or div?
Hi, Is it possible to achieve this effect with CSS only? As you can see, the image on top is distorted along with the text inside to look like the one below. It may be a div or an image. I have been researching on transform but found nothing about curves. This is NOT a duplicate because I am not asking how to curve the text only but the div container as well as in case of an image. Thank you.
I don't know if you would technically qualify this as "CSS only" since it is using an SVG filter, but I think it could be made to achieve the type of warping you want. .warped { display: inline-block; background-color: yellow; padding: 4px; filter: url(#displacement); } #filterSource { display: none; } <span class="warped">Warped Text!</span> <div> <svg id="filterSource" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <defs> <filter id="displacement" filterUnits="userSpaceOnUse"> <!-- this is just a base64 encoded PNG with a simple linear gradient --> <!-- this may not be exactly what you want, but you can adjust the R and B channels to displace the element however you like. --> <feImage href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAdhAAAHYQGVw7i2AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAGlJREFUaIHtz6ENwEAMxVBfUWn3H7Kw8LpCdMjAT/osIF7AZuAGnsMt4D3cN3kOuIZ3eoXYFGJTiE0hNoXYFGJTiE0hNoXYFGJTiE0hNoXYFGJTiE0hNoXYFGJTiE0hNoXYFGJTiE0hNj9ceBBjuV6HJAAAAABJRU5ErkJggg==" result="dispMap" /> <feDisplacementMap in="SourceGraphic" in2="dispMap" scale="10" xChannelSelector="B" yChannelSelector="R" /> </filter> </defs> </svg> </div> Here's a nice tutorial on some cool effects you can achieve with this technique: https://www.creativebloq.com/how-to/add-svg-filters-with-css