Flip vertically a background-image every time it repeat-y
Asked Answered
A

5

28

I'm searching for a trick that repeat my background image vertically, but every time the image is repeated I want to flip it vertically.

I tried all the things in my mind with repeat-y but I don't found a solution, even searching for it in google.

Example:

Background Straight background-image

Background flipped vertically Flipped background-image when it repeat-y

Background flipped vertically again And then flipped again to straight

There is a method to obtain that position?

I'll accept the solution in JScript (and library of it) only if there isn't a solution with pure css.

Thank you all!

Artema answered 30/7, 2013 at 14:13 Comment(2)
You could make one image out of the original and the reversed and set them as background with repeat-yZorina
A decade later, and this is still not possible, even though it would cut the required image size in half for each mirrored axis. Sometimes I think CSS wasn't made with designers in mind (or in this case not with optimization in mind either). Viewed 43k times, nobody can deny there is interest in this feature...Annunciation
H
14

This cannot be done using standard CSS3 since there are no CSS3 properties to rotate a background image.

Reference: http://www.w3.org/TR/css3-background

As suggested, combine the two motifs in a single image, much simpler and will always work.

Hiles answered 30/7, 2013 at 14:21 Comment(0)
L
4

I would load the background image like so

<style>
body{
    background-image:url('mybackground');
    background-repeat:no-repeat;
}
</style>

Background

As the image has already loaded we can do a little JavaScript without the browser doing much extra work. we can check whether the height of the image fills the entire window.

<script>
var el      =  $('body')[0];
var src     =  $(el).css('background-image').slice(4, -1);
var img     =  new Image();

checkHeight =  function(){    
    if(img.height < window.innerHeight){
       repeatBg();     
    }
}
img.onload  =  checkHeight();
img.src = src;
</script>

If the image background does not fill the full height of the window then this background needs repeating/flipping straight away(this will increase load time); otherwise event listeners can be used to trigger the check later on.
The following function draws the image to the canvas element and creates a dataURL. The background-image src is updated to the new dataURL and repeat-background is changed from no-repeat to repeat-y(vertically);
the event listeners are then remove so the function is not called again.

<canvas style="display:none" id="canvas"></canvas>


<script>

repeatBg = function(){  
    var canvas = $('#canvas')[0];
    var ctx = canvas.getContext("2d");
    canvas.width = img.width;
    canvas.height = img.height *2 ;
    ctx.drawImage(img,0,0);
    ctx.scale(1, -1);
    ctx.translate(0, -img.height);
    ctx.drawImage(img, 0, -img.height, img.width, img.height);
    var dataURL = canvas.toDataURL();
    $(el).css({
        'background-image' : 'url('+dataURL+')',
        'background-repeat' : 'repeat-y'
    });    
    $(window).off('load, scroll, resize', checkHeight);        
}
$(window).on('load, scroll, resize', checkHeight);



</script>

And hey presto

flipped

http://jsfiddle.net/dtjones1988/y49rvu73/6/

Laura answered 6/11, 2013 at 10:8 Comment(0)
R
2

Other answers suggested duplicating and merging the background image. That could add extra megabytes to be downloaded, especially for large images. In the case of large images, however, it might be sufficient to tile them as many times as your content requires coverage. Note: This method uses CSS 2D Transforms, which are currently 93% supported. In browsers that are not supported, the transforms would be ignored, which may not even matter depending on the design.

http://jsfiddle.net/skibulk/6hxeg9cu/

.wrap1 {
    transform: scaleY(-1);
    background: url(https://i.sstatic.net/I4hlZ.png) left bottom;
}

.wrap2 {
    transform: scaleY(-1);
    background:
        url(https://i.sstatic.net/I4hlZ.png) repeat-x left top,
        url(https://i.sstatic.net/I4hlZ.png) repeat-x left 500px;
}

Basically I'm using multiple backgrounds repeating horizontally, and offset vertically. Then I reflected the container. The limitation is that the backgrounds don't repeat forever. So if you don't expect your content to push far down the page, this is an option.

Raglan answered 9/10, 2014 at 14:8 Comment(0)
N
1

A purely css solution is not possible imo.

It depends on your image.

If it's a static on which you use to decorate the page, It's best to just modify it by making it two times taller and adding a flipped copy to the bottom part and using that directly via standard css..

If it's a dynamic one, you still can generate new image (original+flipped) as data url via js and use it on your element.

Otherwise, the solution would be duplicating divs, which is always inconvenient...

Nuclease answered 30/7, 2013 at 14:21 Comment(0)
Z
0

According to my comment heres a pure CSS solution.

    yourElementWithBackground{
    background-image : url("http:yourBackgroundURL");
    background-repeat: repeat-y;
    }

Example (run in as full page if it doesn't work here or look at this Fiddle)

body {
    height: 1000px;
    width: 300px;
    background-image : url("http://picload.org/image/odgwcig/unbenannt.png");
    background-repeat: repeat-y;
}
If you rely on using a single image and revert it, you could do some JavaScript magic. Insert elements with absolute positioning and a lower z-index per JavaScript may one with class "reversed" which contains some css transformation to revert it. The Positioning should be done in JS too - for example img1 should have top: 0, img2 top: heightOfImages* 1, img3 top: heightOfImages* 2 and so on. Do this until you reached the height of your parent Element or the User's resolution.

not really pretty but doable

Zorina answered 30/7, 2013 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.