0

I am trying to create a layout similar to this:

Grayscaled letter over background image

I know I can create the "A" using svg or clip-path but the problem is I want to keep the background inside the "A" aligned with the body background i.e if the window resizes the background image will react as a cover reacts and so should the image inside the "A".

I am running out of ideas to how can I accomplish this... the last thing I can think of is using background-attachment: fixed and creating the "A" using complex CSS like lots of divs with different width/height, border radius, translate etc to create the letter "A".

EDIT: I think I didn't made the case clear so please check this Demo of what I am trying to achieve. Note how the grey scale spot stays aligned with the text div when you resize the browser while the background image is set to cover width and height regardless of the view port size & the image inside the spot changes to render the same spot ... I just want to have more complex shape like an A or Z instead of that odd shape.

Imran Bughio
  • 4,811
  • 2
  • 30
  • 53
  • You want to have an image of the 'A' with the rest of the background in grayscale format, and when it resizes the content of that image changes? – Stewartside Oct 04 '16 at 13:27
  • @Stewartside Yes, although if we could have a separate image for inside "A" to have more control would be better, but even just grey scale would be awesome. – Imran Bughio Oct 04 '16 at 13:30
  • @ImranBughio why don't you just use the background image with the A integrated in it with the filters you need? – web-tiki Oct 04 '16 at 13:33
  • @web-tiki I wish it was that simple but the "A" is suppose to align with that text and background image will wrap the whole width of window... – Imran Bughio Oct 04 '16 at 13:35

3 Answers3

5

Here is an approach you could use to be able to place you letter responsively using SVG.

The point is to use the image twice, one is grayscale and the other is normal. Then you can mask the normal image with text (same approach as in this codepen) to let the grayscaled image appear. Here is an example:

svg {
  display: block;
  width: 100%; height: auto;
}
<svg viewbox="0 0 300 200">
  <defs>
    <mask id="textMask" x="0" y="0" width="300" height="200">
      <rect x="0" y="0" width="300" height="200" fill="#fff" />
      <text text-anchor="middle" x="100" y="150" dy="1" font-size="150">A</text>
    </mask>
    <filter id="deSaturate">
      <feColorMatrix in="SourceGraphic" type="saturate" values="0" />
    </filter>
    <image id="image" xlink:href="http://i.imgur.com/RECDV24.jpg" x="0" y="0" width="300" height="200" />
  </defs>
  <use xlink:href="#image" filter="url(#deSaturate)" />
  <use xlink:href="#image" mask="url(#textMask)" />
</svg>
web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • This is a neat trick but I am afraid my problem can not be solved using this technique ... check this [example](https://jsfiddle.net/k7cmxh7q/), As you can see the background image is suppose to cover the entire body while the greyscale element is suppose to stick with the middle section while keeping same position of the main image inside it.. – Imran Bughio Oct 04 '16 at 15:16
  • I guess I am bad at explaining this issue, hope you understood my point this time... – Imran Bughio Oct 04 '16 at 15:17
  • I am planing to go with the example I shared with you all the way i.e making lots of small shapes which combined together looks like that "A"... messy but the only solution that I feel will deliver what I want. – Imran Bughio Oct 04 '16 at 15:18
2

You could use clip-path and point at an SVG <clipPath>. Works in everything except IE.

.wrap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  
  background: url("http://lorempixel.com/1000/700") no-repeat center center;
  background-attachment: fixed;
  
  -webkit-background-size: cover;
  background-size: cover;
}

.txt {
  background: rgba(0, 0, 0, 0.5);
  padding: 20px;
  color: #fff;
  max-width: 500px;
  padding-top: 20px;
  margin: 50px auto;
  position: relative;
}

.a{
  position: absolute;
  left: -100px;
  top: 0;
  width: 100px;
  height: 100px;
  clip-path: url(#tri);
  -webkit-clip-path: url(#tri);

  background: url("http://lorempixel.com/1000/700") no-repeat center center;
  background-attachment: fixed;
  -webkit-background-size: cover;
  background-size: cover;
  
  -webkit-filter: grayscale(100%);
  filter: grayscale(100%);
}
<div class="wrap">
  <div class="txt">
    <div class="a"></div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Enim ipsum, distinctio molestiae iste ab eum tempore excepturi fugit placeat veniam. Hic minus dolorum, reprehenderit atque, nobis rerum. Quis incidunt, beatae!
  </div>
</div>

<svg width="0" height="0">
  <clipPath id="tri" clipPathUnits="objectBoundingBox">
    <path d="M 0.5,0 L 1,1, 0,1 Z
             M 0.5,0.3 L 0.3,0.7 L 0.7,0.7 Z"/>
  </clipPath>
</svg>

Demo fiddle

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • Thanks mate, I really wished this was supported in IE as well, but I guess I will just add a white png with opacity for IE users. – Imran Bughio Oct 04 '16 at 19:29
  • Your `path` tag is working fine but when I export a path from Illustrator it just doesn't work... can you help please? here is the [demo](https://jsfiddle.net/k7cmxh7q/3/) with an half "M" shaped path but instead it's showing rectangle as no clip-path have been applied to it. – Imran Bughio Oct 05 '16 at 07:32
  • When using `clipPathUnits="objectBoundingBox"`, the coordinate values in the path have to be in the range 0 to 1. The fix for your example is to add a transform to the path that scales it down to that range. Working example: https://jsfiddle.net/k7cmxh7q/4/ – Paul LeBeau Oct 05 '16 at 08:52
1

How about something like the filter property? A quick demo can be seen below:

.background {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background: url(http://lorempixel.com/600/400);
}
.background:before {
  content: "A";
  color:white;
  position: absolute;
  font-size: 300px;
  top: 50%;
  left: 50%;
  opacity: 0.4;
  transform: translate(-50%, -50%);
  -webkit-filter: grayscale(100%);
  filter: grayscale(100%);
}
<div class="background">

</div>
jbutler483
  • 24,074
  • 9
  • 92
  • 145