1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Using background-repeat and background-position together

Discussion in 'CSS' started by Nix Wanning, Jul 6, 2007.

  1. #1
    I need to know if there's a way to have background-repeat and background-position in CSS used together.

    Basically, I have a semi-transparent PNG that has a gradient for the first 300px followed by a flat 1px (height) by 200px (width) PNG (repeated vertically till the end of the element). The element does not have a fixed height (eg fluid).
    SEMrush
    The problem I'm facing is getting the 1px PNG to start repeating after 300px, and not before (as background-repeat does it both ways).

    Is there a hack for this?
     
    Nix Wanning, Jul 6, 2007 IP
    SEMrush
  2. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,131
    Likes Received:
    1,696
    Best Answers:
    239
    Trophy Points:
    515
    #2
    Since you have two png's, I assume you have two containers, right?

    The outermost container should have the 1px tiled image on it, the innermost one could then have the 300px high image with no-repeat.

    If I follow your question properly.

    .outerdiv {
    width:200px;
    background:url(images/longtile.png) repeat-y;
    }

    .innerdiv {
    background:url(images/top.png) no-repeat;
    }

    Should be it... though you have the issue that transparancy won't work... if you need the transparancy that is a third container around both with a padding-top of 300px, putting the image there - Then you need to set the innermost div to margin-top:-300px to put it's content over the header image.

    .outerdiv {
    width:200px;
    background:url(images/top.png) no-repeat;
    padding-top:300px;
    }

    .middlediv {
    background:url(images/longtime.png) repeat-y;
    overflow:visible;
    }

    .innerdiv {
    margin-top:-300px;
    position:relative; /* make sure it ends up on top */
    }

    That should do the trick I THINK. Not 100% sure as this is untested. You are probably better off using the first method and not using transparant .pngs.
     
    deathshadow, Jul 7, 2007 IP
  3. Dan Schulz

    Dan Schulz Peon

    Messages:
    6,032
    Likes Received:
    434
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Dan Schulz, Jul 7, 2007 IP
  4. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,131
    Likes Received:
    1,696
    Best Answers:
    239
    Trophy Points:
    515
    #4
    That wasn't what I meant by not working Dan, if the top .png uses transparancy it will show the tiled background through it... which is why the second example goes nuts with extra code to try and force the tiled background down the page with padding/margins.
     
    deathshadow, Jul 8, 2007 IP
  5. Dan Schulz

    Dan Schulz Peon

    Messages:
    6,032
    Likes Received:
    434
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Ah. It was late anyway (you can talk to me about it on IM if you want, but a quick heads up, I was preoccupied with my search engine site at the time and just kinda "drove-by" this post) when I typed that.
     
    Dan Schulz, Jul 8, 2007 IP
  6. Aztral

    Aztral Active Member

    Messages:
    344
    Likes Received:
    15
    Best Answers:
    0
    Trophy Points:
    75
    #6
    Yes you can. But it depends on which way you want to tile, and how your background image is organized (CSS sprite).

    Here's some css i use for a banner...

    div#topleft
    {
    float:left;
    width:170px;
    margin-left:-100%; 
    height:100px;
    background-repeat:no-repeat; 
    background-position: 0px 0px;
    }
    
    div#topcenter
    {
     margin: 0 170px 0 170px;
     height:100px;
     background-repeat:repeat-x; // THIS LINE IS PERTINENT TO YOUR CASE :)
     background-position: 0px -100px;
    }
    
    div#topright
    {
    float:left; 
    width:170px;
    margin-left:-170px; 
    height:100px;
    background-repeat:no-repeat; 
    background-position: -0px -200px;
    }
    
    .bannerbk
    {
    /*background-color:#CCCCCC;*/
    background-image:url(../images/logo.png);
    }
    Code (markup):
    So, basically I'm using a css sprite to pack my banner graphics into 1 file.
    The important here is "topcenter" which uses both repeat and position.

    What I did was I split the photoshopped banner into 3 separate images, then created a new image (logo.png) out of those 3 which has 3 times the height of a single image. The images were pasted in one on top another...

    --------
    |image1|
    --------
    |image2|
    --------
    |image3|
    --------

    I can use background-repeat:repeat-x; for the middle image because in logo.png the separate graphics are arranged top-to-bottom, but i want to tile horizontally.


    Hope this makes sense to ya :)
     
    Aztral, Jul 8, 2007 IP
  7. Nix Wanning

    Nix Wanning Peon

    Messages:
    152
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #7
    Hey guys, apologies for the late reply!

    Dan - I think you misunderstood what I was asking for, but thanks anyways :)

    Aztral, thanks for your tip, tho I needed a repeat-y technique, not a repeat-x. But thanks :)

    deathshadow - Your CSS helped, tho, a negative margin pushed the middlediv up with the innerdiv. Not sure why it did that, but I modified the negative margin to "bottom: 300px;" and it worked!

    the only problem is that the middlediv is now 300px longer than expected :). Thanks heaps tho, I'll try to find a way to solve this small problem.
     
    Nix Wanning, Jul 10, 2007 IP
  8. xLite

    xLite Peon

    Messages:
    1
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #8
    Thank you DeathShadow, you have really saved me!

    Also thank you Nix Wanning for the bottom: 300px idea that worked great.


    Finally, to add my part in all this (I understand this thread was from 2007, but it will help users when searching for fixes via Google etc, such as myself) the way I managed to get rid of the excess 300px was to use Javascript.

    I used Prototype to listen for the dom:loaded event then simply set the height of middediv to it's current height minus 300 pixels. As it runs as soon as the DOM is loaded, it happens pretty much instantly so there's no weird delays which would mean you could see the div before the height modification.

    Here's the code I use with the Prototype library:
    
    var loader = 
    {
    	onLoadHandler : function()
    	{
    		$("middlediv").style.height = ($("middlediv").offsetHeight - 300) + "px";
    	}
    }
    
    document.observe("dom:loaded", loader.onLoadHandler);
    
    Code (markup):
     
    xLite, Feb 5, 2011 IP