Jashwant
Jashwant

Reputation: 28995

Background position seems to be inaccurate

I've an image and I have put a mask over it.

The mask is divided into 3 equal parts. Each part has the same image as its background. Each part has 1/3rd portion of image. I am changing background position of each part, so the masks (collectively) look exactly like the image.

Everything works great, but 2nd part has some issue in background-image, and it looks few pixels shifted to the right.

I need to remove that shifting.

Demo

HTML:

<div id="wrapper">
    <div id="main">
        <img src="http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg" />
    </div>
    <div id="mask">
        <div class="part part1"></div>
        <div class="part part2"></div>
        <div class="part part3"></div>
    </div>
</div>
<br>
<button id="switcher" class="main">Put mask on top</button>

CSS:

img {
    width: 100%;
    height: 100%;
}
#wrapper {
    position: relative;
    width: 390px;
    height: 300px;
}
#main {
    z-index: 2;
}
#mask {
    z-index: 1;
}
#main, #mask, .part {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
.part {
    background-image: url('http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg');
    background-size: 390px 300px;
    width: 130px;
}
.part2 {
    background-position: -130px 0;
    left: 130px;
}
.part3 {
    background-position: -260px 0;
    left: 260px;
}

JS:

$('#switcher').click(function () {
    if ($(this).hasClass('main')) {
        $(this).html('Put mask on top').removeClass('main');
        $('#main').css({
            zIndex: 1
        });
        $('#mask').css({
            zIndex: 2
        });
    } else {
        $(this).html('Put main on top').addClass('main')
        $('#main').css({
            zIndex: 2
        });
        $('#mask').css({
            zIndex: 1
        });
    }
});

Upvotes: 2

Views: 312

Answers (2)

Jashwant
Jashwant

Reputation: 28995

As pointed out by Dharmang, cause of the issue was aspect ratio of image. And, it was not possible to fix, without changing the #wrapper dimension, or the image itself.

I've found a workaround, but using img tag, instead of background-image, so that I can distort the aspect ratio of images of mask div, in equal amount, as it is destroyed by the 'real image'.

$('#switcher').click(function () {
    if ($(this).hasClass('main')) {
        $(this).html('Put mask on top').removeClass('main');
        $('#main').css({
            zIndex: 1
        });
        $('#mask').css({
            zIndex: 2
        });
    } else {
        $(this).html('Put main on top').addClass('main')
        $('#main').css({
            zIndex: 2
        });
        $('#mask').css({
            zIndex: 1
        });
    }
});
img {
    width: 100%;
    height: 100%;
}
#wrapper {
    position: relative;
    width: 390px;
    height: 300px;
}
#main {
    z-index: 2;
}
#mask {
    z-index: 1;
}
#main, #mask, .part {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
.part {
    width: 130px;
}

.part img {
    margin-left: 0;
    width: 390px;
    height: 300px;
}

.part2 {
    left: 130px;
}

.part2 img {
    margin-left: -130px; 
}

.part3 {
    left: 260px;
}

.part3 img {
    margin-left: -260px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="wrapper">
    <div id="main">
        <img src="http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg" />
    </div>
    <div id="mask">
        <div class="part part1"><img src="http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg" /></div>
        <div class="part part2"><img src="http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg" /></div>
        <div class="part part3"><img src="http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg" /></div>
    </div>
</div>
<br>
<button id="switcher" class="main">Put mask on top</button>

Upvotes: 2

Dharmang
Dharmang

Reputation: 3028

It is because you are using image of dimension 425x318 and resizing background to 390x300, so image gets distorted as aspect ratios of them do not match.

Check updated demo, here I have used wrapper dimension of same size as of image, i.e. 425x318.

JS Fiddle Demo

Update in code:

CSS

Remove background-size from .part and change #wrapper width, height.

img {
    width: 100%;
    height: 100%;
}
#wrapper {
    position: relative;
    width: 425px;
    height: 318px;
}
#main {
    z-index: 2;
}
#mask {
    z-index: 1;
}
#main, #mask, .part {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
.part {
    background-image: url('http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg');
    /*background-size: 390px 300px;*/
    width: 130px;
}
.part1 {
    background-position: 0 0;
    left: 0;
}
.part2 {
    background-position: -130px 0;
    left: 130px;
}
.part3 {
    background-position: -260px 0;
    left: 260px;
}

UPDATE:

As you mentioned in comment that Image is not in control, background-size properties contain and cover also not working.

The only feasible option seems to get the image dimensions by some method (javascript OR server side code) and dynamically set the #wrapper dimensions to match image dimensions.

JavaScript Code: (For getting image dimensions and set Wrapper dimensions accordingly)

http://jsfiddle.net/8au8nhe5/19/

$(document).ready(function() {
    var myImage = new Image();
    myImage.src = "http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg";
    $(myImage).on('load', function() {
        console.log('My width is: ', this.naturalWidth);
        console.log('My height is: ', this.naturalHeight);
        $("#wrapper").css({"width": this.naturalWidth + "px", "height": this.naturalHeight + "px"});
    });
});

For Reference:
http://davidwalsh.name/get-image-dimensions
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement

Upvotes: 4

Related Questions