SanJeet Singh
SanJeet Singh

Reputation: 1331

Apply three CSS filters side by side on an image?

Have a look at the following CodePen demo: http://codepen.io/anon/pen/vLPGpZ

This is my code there:

  body {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: url(http://lorempixel.com/900/300) no-repeat center center fixed;
  }

  body:before {
    left: 0;
    right: 0;
    content: "";
    position: fixed;
    height: 100%;
    width: 30%;
    background: url(http://lorempixel.com/900/300) no-repeat center center fixed;
    filter: sepia(1);
  }

You will see a sepia filter applied. What I want is to apply three CSS filters on same image side by side. First 1/3 part with grayscale filter, middle 1/3 part with sepia filter, last 1/3 part with contrast filter. How can I achieve this with or with jQuery or JavaScript?

Right now, even the one third part is not being covered correctly with Sepia.

Upvotes: 4

Views: 748

Answers (4)

Guilherme Lúcio
Guilherme Lúcio

Reputation: 92

I saw someone already replied, but I think the effect is better if you make it responsible. For doing this add the following HTML

<div class="container">
  <div class="wrapper grayscale">
    <div class="picture"></div>
  </div>
  <div class="wrapper original">
    <div class="picture"></div>
  </div>
  <div class="wrapper sepia">
    <div class="picture"></div>
  </div>
</div>

And the CSS

.container {
  height: 300px;
  max-width: 900px;
  margin: 100px 0 0 0;
  position: relative;
  width: 100%;

}

.wrapper {
  height: 300px;
  float: left;
  max-width: 900px;
  overflow: hidden;
  position: relative;
  width: 33.3%;
}

.picture {
  background-image: url(http://lorempixel.com/900/300);
  background-repeat: no-repeat;
  background-size: 900px;
  background-position: left 100px;
  background-attachment: fixed;
  height: 300px;
  left: 0;
  position: absolute;
  top: 0;
  width: 900px;
}

.grayscale .picture {
  -webkit-filter: grayscale(1);
  filter: grayscale(1);
}

.picture.original {
}

.sepia .picture {
  -webkit-filter: sepia(1);
  filter: sepia(1);
} 

The main trick is to use a css property to make the background fixed.

background-attachment: fixed;

Please, take a look at the example: http://codepen.io/guilhermelucio/pen/obVLpd

Upvotes: 0

vals
vals

Reputation: 64254

An alternate way to this is to use blend mode instead of filters.

This way, you have greater flexibity at the time to set your layout, (for instance, you can set the image as a background with size: cover)

You only need to know the blend mode equivalents of those filters

.base {
  position: absolute;
  left: 0px;
  top: 0px;
  width: 600px;
  height: 300px;
  background-image: url(http://lorempixel.com/400/200);
  background-size: cover;
}

.filter {
  position: absolute;
  left: 0px;
  top: 0px;
  width: 600px;
  height: 300px;
}

.filter div {
  width: calc(100% / 3);
  height: 100%;
  position: absolute;
  top: 0px;
}

.gray {
  background-color: gray;
  mix-blend-mode: color;
  left: 0px;
}

.sepia {
  background-color: rgb(112, 66, 20);
  mix-blend-mode: color;
  left: calc(100% / 3);
}

.contrast {
  background-color: hsl(128,100%,50%);
  mix-blend-mode: saturation;
  left: calc(200% / 3);
}
<div class="base"></div>
<div class="filter">
<div class="gray"></div>
<div class="sepia"></div>
<div class="contrast"></div>
</div>

Upvotes: 2

aug
aug

Reputation: 11714

EDIT: I see someone posted an answer already but I'll just post mine since I did it a little differently.

If you want to have them sectioned off correctly, you are going to need to split it up into different elements for each filter. You'll also need to have each element have its own background set so the filter can apply to its own section of the image and you'll need to set the position accordingly (you don't have to worry about requests because it'll only request the background image once).

Also the reason in yours the first section wasn't 1/3 is because you set it to 30% when 1/3 is technically 33.33% (repeating of course).

I made a codepen here.

.container {
   position: relative;
   width: 900px;
   height: 300px;
}

.filter-section {
  float: left;
  width: 33.333333333%;
  height: 100%;
  background: url(http://lorempixel.com/900/300) no-repeat;
}
    

.grayscale {
  -webkit-filter: grayscale(1);
  filter: grayscale(1);
  background-position: left;
}

.sepia {
  -webkit-filter: sepia(1);
  filter: sepia(1);
  background-position: center;
}

.contrast {
  -webkit-filter: contrast(200%);
  filter: contrast(200%);
  background-position: right;
}
<div class="container">
  <div class="grayscale filter-section"></div>
  <div class="sepia filter-section"></div>
  <div class="contrast filter-section"></div>
</div>

Upvotes: 6

Pedram
Pedram

Reputation: 16615

Here you go, JSFiddle

    body {
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      background: url(http://lorempixel.com/900/300) no-repeat center center fixed;
      -webkit-filter: contrast(1);
      filter: contrast(1);
    }

body:before {
    right: 0;
    top: 0;
    content: "";
    position: fixed;
    height: 100%;
    width: 33%;
    background: url(http://lorempixel.com/900/300) no-repeat right center fixed;
    -webkit-filter: sepia(1);
    filter: sepia(1);
}

body:after {
    left: 0;
    top: 0;
    content: "";
    position: fixed;
    height: 100%;
    width: 33%;
    background: url(http://lorempixel.com/900/300) no-repeat left center fixed;
    -webkit-filter: grayscale(1);
    filter: grayscale(1);
}

or this width repeated background:

JSFiddle

Upvotes: 2

Related Questions