1

I've been trying to figure out why my code below doesn't work as expected. Basically I want the ups img to have width: 60px and fedex img to have width: 100px.

My mark up is:

<div class="delivery-services">
    <span>Delivery Services</span>
    <br>
    <a href="#"><img src="img/fedex.png" alt="fedex" /></a>
    <a href="#"><img src="img/ups.png" alt="ups" /></a>
</div>

SCSS is:

.delivery-services {

  &:nth-child(3) img  {
    width: 100px;
  }

  &:last-child img {
    width: 60px;
  }
}

But it appears that both img are affected by last-child!

Jim
  • 1,027
  • 1
  • 10
  • 19
  • See http://stackoverflow.com/questions/15149641/do-i-need-a-at-the-end-of-an-img-or-br-tag-etc for unrelated issue about closing `img` tag. –  Sep 23 '16 at 04:35
  • Thanks, this is the pen http://codepen.io/anon/pen/YGNgkj – Jim Sep 23 '16 at 04:47
  • Well, `delivery-services` **is** the last child of its parent. Try adding a space after your `&`. The devtools style inspector is your friend here. –  Sep 23 '16 at 04:53
  • 1
    @Jim, take a look at my [answer](http://stackoverflow.com/a/39652886/2545680), I've explained what happens under the hood – Max Koretskyi Sep 23 '16 at 05:06

3 Answers3

3

Here is how a browser processes your selector .delivery-services:last-child img:

  1. Find the element with the class .delivery-services and make sure it's the last child. It finds <div class="delivery-services"> and it's indeed a last child. If you changed your HTML a bit like this:

    <div class="delivery-services">
        <span>Delivery Services</span>
        <br>
        <a href="#"><img src="img/fedex.png" alt="fedex" /></a>
        <a href="#"><img src="img/ups.png" alt="ups" /></a>
    </div>
    <div>I am last child now</div>`
    

    You would see that your selector doesn't match any img element.

  2. Find all img elements inside the element found on first step

That's why the style width: 60px; is applied to all img elements.

I would also advise you to use classes on those images. nth-child selector is a good fit for recurring patters, like, for example, every 3rd row has to have green background.

Here is the fix to your problem if you need to use nth-child selector:

.delivery-services {

  :nth-child(3) img  {
    width: 100px;
  }

  :last-child img {
    width: 60px;
  }
}
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • Thanks, Im on scss so in my file it should be `&:nth-..` (y) – Jim Sep 23 '16 at 05:25
  • @Jim, you can accept my answer if it answers your question :). If you write like this `&:nth-.`, it will be what you had in the beginning. My version should work OK. – Max Koretskyi Sep 23 '16 at 05:31
1

Right now you have .delivery-services::nth-child(3), which means it applies to the .delivery-services element that is the 3rd child of a parent. That's not what you're looking for. You are looking for an <a> that is the 3rd child of .delivery-services. So you need your CSS to be:

.delivery-services {

  & a:nth-child(3) img  {
    width: 100px;
  }

  & a:last-child img {
    width: 60px;
  }
}
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
grayimp
  • 358
  • 2
  • 9
1

When working with CSS, you have to consider the order of operations. In the example you provided, think about the hierarchy that. When applying the style it is setting it to the top and working down. For instance, delivery-services -> a -> img. To apply this to the sub classes, understand you are looking for the image inside the first a. Therefore, I'd set it up similar to:

.delivery-services a:nth-child(4) img{
    width: 100px;
  }
.delivery-services a:nth-child(3) img{
  width: 60px;
}

However, for specific instances such as this, I'd assign a different class to each instance or inline styling. nth-child is ideal for loops and iterations.