Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

CSS

Jennifer Hinkle
Jennifer Hinkle
8,365 Points

using bacground-size: cover property for div instead of viewport

Hello,

I've designed websites before with a full-page background using this code:

background: url(img/bg.jpg) #39403D no-repeat center center fixed; 
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;

(thanks to Chris Coyier at CSS Tricks)

This time, however, I want the background image to fully cover a div instead of the entire viewport. Meaning, instead of the image covering 100% of the width, I only want it to cover 65% of the width of the page (with 100% height). Also, I want the image to stay proportional so it doesn't distort by me setting it manually to width: 65%; height: 100%;

I tried playing with background-size: percentages; but that only works with one dimension, not both height and width (unless I let my picture become distorted). Meaning, if I set the height to 100% and the width to auto and I resize my browser to be short and fat, the image quickly doesn't cover the whole area. There is a big strip next to the image that is blank. And vise versa, if I set the width to 65% and the height to auto and then re-size my browser to be tall and narrow, a big area under the photo becomes blank.

I'm sorry if that description is confusing. Basically I'm asking if there is a way to have "cover" refer to the size of my div instead of the size of my viewport.

Or if that doesn't actually work, if anyone has a different suggestion! (And doesn't have to be a CSS suggestion, JS/ jQuery advice is also appreciated if you think it'll be easier).

As always, I'm grateful for any help!

Thanks, Jenn

3 Answers

Andrew Shook
Andrew Shook
31,709 Points

Yes, it does have to do with the way the .image is position:absolute. Without knowing your design goals, I went ahead and made some modifications to your html and added some CSS. This may not be exactly what your are looking for but it should get you close.

<header  class="container clearfix">
    <nav class="main-nav">
        <ul>
            <li>Home</li>
            <li>About</li>
            <li>etc</li>
        </ul>
    </nav>
</header>
<div class="container clearfix">
    <div class="image"></div>

    <div class="content">
        <p>Here is some content!</p>    
    </div>
</div>

and the CSS:

.main-nav{
    background-color: red;
    color: white;
}
    .image{
        background-image: url("url/to/image.png");
         width: 65%;
         height: 100%;
         position: absolute;
         background-color: black;
         background-size: cover;
         background-position: center center;
    }
    .content {
        text-align: center;
        background: black;
        color: white;
        width: 35%;
        height: 1200px;
        margin-left: 65%;
    }
    .container{
            position: relative;
        width: 100%
    }

So I wrapped the main nav in a header tag and changed the main menu parent to nav for good HTML5 markup. I put the main nav in its own container so that you wouldn't run into the issue of you content overlapping it. Then I gave the containers a position of relative so that any of their child elements positioned absolutely would position themselves to the container and not the page. Since absolutely positioned elements don't take up "physical" space on the screen, I gave the content a margin-left of 65% so that it would be pushed out of the way of the .image element. Also, I gave the .content and .main-nav bg-color so that you could see where that element starts and ends on the screen. I hope this is helpful, and let me know if you need any more advise.

Jennifer Hinkle
Jennifer Hinkle
8,365 Points

Thanks for your help! I'm playing with the code now and I've basically got it perfect!

What I'm trying to achieve is for .image to take up 65% with, .content to fill remaining width, while the nav stretches across the top of the page, sitting on top of both divs. And all of this is covering 100% of the viewport (with no scroll- except content can scroll in it's div).

Between what I've been doing and your help I think I'm really close! So thanks so much!

Jenn

Andrew Shook
Andrew Shook
31,709 Points

Cover does refer to the width and height of the element that background is placed on. Cover also maintains the aspect ratio of the image. However, if the aspect ratio of the image differs drastically from the aspect ratio of the element the background is applied to, then the part of the image will be cut off. Those part are dependent on the back-position setting. So if the background-position is set to center then both the sides and the top/bottom should be cut off equally. The only real problem you are going to run into is if you put a landscape style image on an element has portrait ratios. In other words, 9x16 image + 16x9 element = bad. If that is the case, then I suggest changing images or the one you have (assuming it has enough resolution to do so) so that it better matches the proportions of the element you are going to set it as a background to.

Jennifer Hinkle
Jennifer Hinkle
8,365 Points

Hi Andrew,

Thanks for the reply! I understand that the image will get cut off to maintain the aspect ratio, and what you describe is exactly what I was hoping would happen. However, it looks as if it's covering the entire viewport as opposed to sizing itself to my div. Even if I make the browser window sized so that div is about the same aspect ratio of the desired image, way more of the right side of the picture is cut off as if it's centered to the viewport as opposed to this div which is aligned left.

Maybe it's because this div doesn't actually have any content in it?

<div class="image></div>
.image {
    width: 65%;
    height: 100%;
    position: absolute;
    display: inline-block;
}

Thanks again, Jenn

Andrew Shook
Andrew Shook
31,709 Points

is the image div a child of another div?

Jennifer Hinkle
Jennifer Hinkle
8,365 Points

Yes, it's a child of the .container div. There are two other div's on it's level, the .nav div and the .content div.

I have this .image div width = 65% and the .content div width = 35% while the .nav is 100% and sits at the top of the page, this is how the html is basically structured:

<div class="container">
    <div class="nav">
        <ul>
            <li>Home</li>
            <li>About</li>
            <li>etc</li>
        </ul>
    </div>

    <div class="image"></div>

    <div class="content">
        <p>Here is some content!</p>    
    </div>
</div>
Jennifer Hinkle
Jennifer Hinkle
8,365 Points

To add a bit more info after playing more...

I tried adding some text into the div.image with a width = 65%;

When I said "text-align: center;" my text centered to the viewport, not the div. I have no idea why any of this is happening. My div is 65% wide (and it's not hiding behind another div because I did "display: none;" on the rest of the content to see if the background actually extended all the way, which it doesn't).

Maybe it has something to do with the position property?

Again, any help suuper appreciated!

Thanks! Jenn