0

I am working on a category section where the image hasImage has a category on the top right, titles on the bottom left and a linear gradient at the bottom i.e., the background of the titles. Using a pseudo class :after I want to insert the linear gradient to the background. As you can see the image is in the HTML tag not in the background but it won't work even when I give z-index. What am I doing wrong?

Any Suggestions and help are appreciated.

Thanks in advance.

a {
  text-decoration: none;
}

.category-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  list-style-type: none;
}

.category-list li {
  flex: 0 1 31%;
  position: relative;
}

.category-details img:after {
  display: block;
  position: absolute;
  width: 100%;
  height: 103px;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.4), rgb(0, 0, 0, 0.7));
  z-index: 999;
}

.category {
  position: absolute;
  top: 10%;
  right: 10%;
  background-color: #00ae6f;
  color: #ffffff;
  padding: 0px 10px;
}

.category-details {
  position: relative;
}

.overlay-title {
  position: absolute;
  bottom: 10%;
  left: 10%;
  color: #fff;
}

.overlay-title h3 {
  font-size: 20px;
  font-weight: 700;
}

.overlay-title h5 {
  font-size: 14px;
  font-weight: 200;
}
<ul class="category-list">
  <li>
    <div class="category-details">
      <img class="category-img" src="https://image.ibb.co/dWGHdG/kimberlyphoto_medium.jpg" />
      <a href="#" class="category">Education</a>
      <div class="overlay-title">
        <h3>Elementary school</h3>
        <h5>297 stephens st. pressville</h5>
      </div>
    </div>
  </li>
  <li>
    <div class="category-details">
      <img class="category-img" src="https://preview.ibb.co/eEi2Cb/CBSE_Building_design_plans.jpg" />
      <a href="#" class="category">Education</a>
      <div class="overlay-title">
        <h3>Elementary school</h3>
        <h5>297 stephens st. pressville</h5>
      </div>
    </div>
  </li>
  <li>
    <div class="category-details">
      <img class="category-img" src="https://image.ibb.co/dWGHdG/kimberlyphoto_medium.jpg" />
      <a href="#" class="category">Education</a>
      <div class="overlay-title">
        <h3>Elementary school</h3>
        <h5>297 stephens st. pressville</h5>
      </div>
    </div>
  </li>
</ul>
Mohammed Wahed Khan
  • 836
  • 2
  • 14
  • 35
  • 1
    Try `:after` on some element other than `img`. – Mohammad Usman Nov 07 '17 at 07:14
  • I know that I could take that image in a div and give the linear gradient to that div but why can't I give it to the image. – Mohammed Wahed Khan Nov 07 '17 at 07:16
  • 1
    You need to add `content: ''` and fix a typo in `linear-gradient()` method. You are using `rgb` which does't accept alpha channel. It must be `rgba` to work correctly. – Mohammad Usman Nov 07 '17 at 07:18
  • 1
    Unfortunately `:after` and `:before` on `img` doesn't work on most browser referring to these answers: [Solution-1](https://stackoverflow.com/questions/5843035/does-before-not-work-on-img-elements) and [Solution-2](https://stackoverflow.com/questions/6949148/css-after-not-adding-content-to-certain-elements). hope this helps. – Mhd Alaa Alhaj Nov 07 '17 at 07:23
  • @mohammed Usman It worked with your suggestions. Can you answer the thing you just said so that I could accept it. – Mohammed Wahed Khan Nov 07 '17 at 07:27
  • @Mohammedwahedkhan There are already two answers with the similar solutions. Its not good idea to post the same idea again. You can accept any one of them. That's is perfectly fine as far as your problem is solved :) – Mohammad Usman Nov 07 '17 at 07:30
  • @mohammed Usman But you were the first to tell me and it worked when I've tried, So legally your answer should be accepted. Anyways It worked Shukran. – Mohammed Wahed Khan Nov 07 '17 at 07:37

5 Answers5

3

There are a few problems

  1. Use ::after instead of :after.
  2. An img can't have a pseudo element. Sorry.
  3. A pseudo element should have content: ""; property otherwise it wouldn't appear at all.

Use ::after on the category-details and make sure that any other element insidw .category-details has a greater z-index (the text, i.e the title etc) otherwise it will be behind the ::after element.

Deepak Kamat
  • 1,880
  • 4
  • 23
  • 38
2

First thing; CSS pseudo-elements are not going to work on the img element. Why? Read some about it here.

Secondly; you've also been making a little mistake in the linear-gradient CSS function. In the code above, you are/were using rgb(0, 0, 0, 0.4) instead of rgba(0, 0, 0, 0.4), I think I don't need to talk more about this as unlike rgba() the rgb function doesn't allow you to use an alpha value.

Here is my quick take on what you are trying to achieve.

/* Used the box-sizing reset to avoid sizing issues */

*,
*:after,
*:before {
  box-sizing: border-box;
}

a {
  text-decoration: none;
}


/* Killed that annoying additional margin below the images */

img {
  vertical-align: bottom;
}

.category-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  list-style-type: none;
}

.category-list li {
  flex: 0 1 31%;
}


/* Relatively-positioned the `.overlay-title` container */

.category-list li,
.category-details {
  position: relative;
}

.category {
  position: absolute;
  top: 10%;
  right: 10%;
  background-color: #00ae6f;
  color: #ffffff;
  padding: 0px 10px;
}

.category-details {
  position: relative;
  color: #fff;
}


/* Made the appropriate positioning, display, and background changes to the overlay div. This will do the job. */

.overlay-title {
  position: absolute;
  bottom: 0;
  left: 0;
  padding: 2em;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  justify-content: flex-end;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0));
  background-size: 100% 50%;
  background-position: 0 100%;
  background-repeat: no-repeat;
  z-index: 999;
}

.overlay-title h3 {
  font-size: 20px;
  font-weight: 700;
}

.overlay-title h5 {
  font-size: 14px;
  font-weight: 200;
}


/* Gave some margin to make the overlay text look good */

.overlay-title h3,
.overlay-title h5 {
  margin: 0 0 1em;
}
<ul class="category-list">
  <li>
    <div class="category-details">
      <img class="category-img" src="https://image.ibb.co/dWGHdG/kimberlyphoto_medium.jpg" />
      <a href="#" class="category">Education</a>
      <div class="overlay-title">
        <h3>Elementary school</h3>
        <h5>297 stephens st. pressville</h5>
      </div>
    </div>
  </li>
  <li>
    <div class="category-details">
      <img class="category-img" src="https://preview.ibb.co/eEi2Cb/CBSE_Building_design_plans.jpg" />
      <a href="#" class="category">Education</a>
      <div class="overlay-title">
        <h3>Elementary school</h3>
        <h5>297 stephens st. pressville</h5>
      </div>
    </div>
  </li>
  <li>
    <div class="category-details">
      <img class="category-img" src="https://image.ibb.co/dWGHdG/kimberlyphoto_medium.jpg" />
      <a href="#" class="category">Education</a>
      <div class="overlay-title">
        <h3>Elementary school</h3>
        <h5>297 stephens st. pressville</h5>
      </div>
    </div>
  </li>
</ul>

I didn't use pseudo-elements in the above example, I applied the gradient to the overlay division instead, with some additional settings like setting left and bottom to zero and provided some size to make it look good.

Consider using the box-sizing reset in your projects to avoid sizing issues.

Using flexbox was a little tricky here, as I needed the overlay division to have some size (100% of the available space), and then I needed to align the contents to the bottom. This might make you to use an inner division for the alignment sake, which I tried avoiding by making use of Flexbox columns.

We should not forget the other background properties here, like background-repeat, background-size, and background-position. They will help you position the gradient perfectly as you might have seen already in the example snippet above.

Hope this was helpful. Cheers!

Rahul
  • 822
  • 6
  • 12
1

You can only add pseudo elements to certain elements like spans, li's, anchor tags, p and h elements. Try throwing a span in the containing div and style that to give you a gradient.

The after style also needs a content: ' '; to tell the DOM that there is something after.

1

It's not possible to add an :after psuedo-element to an img element. But you can add the background to an :after psuedo-element on the .category-details and use z-index to position the text over the gradient.

Also, don't forget the browser prefixes.

a {
  text-decoration: none;
}

.category-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  list-style-type: none;
}

.category-list li {
  flex: 0 1 31%;
  position: relative;
}

.category {
  position: absolute;
  z-index: 1000;
  top: 10%;
  right: 10%;
  background-color: #00ae6f;
  color: #ffffff;
  padding: 0px 10px;
}

.category-details {
  position: relative;
}

.category-details:after {
  content: "";
  z-index: 100;
  position: absolute;
  border-radius: 16px;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.7));
  background: -o-linear-gradient(bottom, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.7));
  background: -moz-linear-gradient(bottom, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.7));
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.7));
}

.overlay-title {
  position: absolute;
  z-index: 1000;
  bottom: 10%;
  left: 10%;
  color: #fff;
}

.overlay-title h3 {
  font-size: 20px;
  font-weight: 700;
}

.overlay-title h5 {
  font-size: 14px;
  font-weight: 200;
}
<ul class="category-list">
  <li>
    <div class="category-details">
      <img class="category-img" src="https://image.ibb.co/dWGHdG/kimberlyphoto_medium.jpg" />
      <a href="#" class="category">Education</a>
      <div class="overlay-title">
        <h3>Elementary school</h3>
        <h5>297 stephens st. pressville</h5>
      </div>
    </div>
  </li>
</ul>
Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
0

You can get exactly what you need by adding div or span next to image as below. I have added <div class="bottom-gradient"></div> next to image.

a {
  text-decoration: none;
}

.category-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  list-style-type: none;
}

.category-list li {
  flex: 0 1 31%;
  position: relative;
}

.category-details img:after {
  display: block;
  position: absolute;
  width: 100%;
  height: 103px;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.4), rgb(0, 0, 0, 0.7));
  z-index: 999;
}

.category {
  position: absolute;
  top: 10%;
  right: 10%;
  background-color: #00ae6f;
  color: #ffffff;
  padding: 0px 10px;
}

.category-details {
  position: relative;
}

.overlay-title {
  position: absolute;
  bottom: 10%;
  left: 10%;
  color: #fff;
}

.overlay-title h3 {
  font-size: 20px;
  font-weight: 700;
}

.overlay-title h5 {
  font-size: 14px;
  font-weight: 200;
}

.bottom-gradient {
  background: rgba(0, 0, 0, 0) linear-gradient(0deg, rgb(0, 0, 0) 0%, rgba(0, 0, 0, 0.4) 23%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0) 68%, rgba(0, 0, 0, 0) 81%, rgba(0, 0, 0, 0) 92%, rgba(0, 0, 0, 0) 100%) repeat scroll 0 0;
  bottom: 0;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
}
<ul class="category-list">
  <li>
    <div class="category-details">
      <img class="category-img" src="https://image.ibb.co/dWGHdG/kimberlyphoto_medium.jpg" />
      <div class="bottom-gradient"></div>
      <a href="#" class="category">Education</a>
      <div class="overlay-title">
        <h3>Elementary school</h3>
        <h5>297 stephens st. pressville</h5>
      </div>
    </div>
  </li>
  <li>
    <div class="category-details">
      <img class="category-img" src="https://preview.ibb.co/eEi2Cb/CBSE_Building_design_plans.jpg" />
      <div class="bottom-gradient"></div>
      <a href="#" class="category">Education</a>
      <div class="overlay-title">
        <h3>Elementary school</h3>
        <h5>297 stephens st. pressville</h5>
      </div>
    </div>
  </li>
  <li>
    <div class="category-details">
      <img class="category-img" src="https://image.ibb.co/dWGHdG/kimberlyphoto_medium.jpg" />
      <div class="bottom-gradient"></div>
      <a href="#" class="category">Education</a>
      <div class="overlay-title">
        <h3>Elementary school</h3>
        <h5>297 stephens st. pressville</h5>
      </div>
    </div>
  </li>
</ul>
RaJesh RiJo
  • 4,302
  • 4
  • 25
  • 46