Pregunta

I am trying to put a ribbon that is as wide as my content but 'spill' the sides over to the body. Example here. This is the HTML I have so far. There are three images: the middle part of the ribbon and then two sides. I put the middle part in the h1 and now I am trying to line up the sides.

<body>

  <div id="container">

   <div id="leftside">
   </div>

   <div id="rightside">
   </div>


   <div id="content">

      <header>
          <h1>This is the body of the ribbon</h1>
      </header>
   </div>
</div>

</body>  

My shot at the CSS. I've been experimenting and this does what I need it to but I am sure there are a million better solutions. I want to know what the best practice would be for this since I am sure I'm kind of breaking a lot of rules here.

#container {
    width: 825px;
    min-height: 960px;
    margin: 0 auto;
}

#left {
     background-image: url(side.jpg);
     background-repeat: no-repeat;
     width: 59px;
     height: 48px;
     position: absolute;
     margin-top: 20px;
     margin-left: -58px;

 }

#right {
    background-image: url(side.jpg);
    background-repeat: no-repeat;
    width: 59px;
    height: 48px;
    position: absolute;
    margin-top: 20px;
    margin-left: 825px;
}

#content {
    width: 825px;
    min-height: 700px;
    margin: 0 auto;
    background: url(other.jpg) repeat;
    margin-top: 20px;
    margin-bottom: 20px;
    top:0;
    overflow: auto;
}

h1 {
    text-indent: -9999px;
    background-image: url(banner.jpg);
    background-repeat: repeat-x;
    margin-top: 0;
    height: 48px;
}
¿Fue útil?

Solución

There definitely are a million ways to accomplish this. The best approach will depend greatly on how your site progresses.

What it comes down to is relative and absolute positioning.

One way to accomplish this is to structure your site something like so:

<body>
    <div id="header">
        <div id="ribboncenter"></div>
        <div id="ribbon1"></div>
        <div id="ribbon2"></div>
    </div>

    <div id="content">
        Your content
    </div>

    <div id="footer">
        Your footer
    </div>
</body>

That's very loose frameworking for a typical site. The CSS would be something like so:

#header{
    width:800px; //Subjective to however big you want your site
    margin:0 auto; //Positions the header in the center
    position:relative; //Tells nested absolute elements to base their positions on this
}
#ribbon1, #ribbon2{
    position:absolute; //Position is now based on #header and is pulled from the regular DOM flow
    width:50px; //Subjective to whatever the width of your "ribbon" is
    top:10px; //Subjective to how far down from the top of #header you want it
}
#ribboncenter{
    width:100%; //Sets width to the width of #header
    background:url(ribboncenter.png); //Subjective to image
#ribbon1{
    left:-50px; //Subjective to the width of the image, moves it 50px left of #header
    background:url(my-ribbon1.png); //Subjective to whatever your image is
}
#ribbon2{
    right:-50px; //Subjective to the width of the image, movesit 50px right of #header
    background:url(my-ribbon2.png); //Subjective to whatever your image is
}

Here's the example http://jsfiddle.net/NZ8EN/

This is all very loose but hopefully gives you an idea of the direction to take.

There are definitely other ways to solve this as well.

Otros consejos

Try putting the #right and #left divs inside the #content div, give #content a position of relative (so that it becomes the parent reference for the children #left and #right) and position absolutely the #left and #right:

HTML:

<body>
    <div id="container">
      <div id="content">
            <div id="leftside"></div>
            <div id="rightside"></div>
          <header>
              <h1>This is the body of the ribbon</h1>
          </header>
       </div>
    </div>
</body>  

CSS:

#left {
    position: absolute;
    top: 0;
    left: -59px;
}
#right {
    position: absolute;
    top: 0;
    right: 59px;
}

Unless you're supporting IE7, I'd probably go with something like this:

http://jsfiddle.net/G5jkt/

This is the CSS you'd need to add:

h1 {
    position: relative;
}

h1:before {
    content: '';
    height: 100%;
    left: -59px;
    top: 0;
    position: absolute;
    background-image: url(side.jpg);
    background-repeat: no-repeat;
    width: 59px;
}

h1:after {
    content: '';
    width: 59px;
    height: 100%;
    background-image: url(side.jpg);
    background-repeat: no-repeat;
    right: -59px;
    top: 0;
    position: absolute;
}

And you've have to change your HTML like so:

<div id="container">
  <div id="content">
    <header>
      <h1>Hello Here</h1>
    </header>
  <div>
</div>

Using :before and :after helps remove design specific HTML from the document and gets the job done.

The key is using absolute positioning. In your example, you have your ribbon ends at the top of the page -- they have no relationship with the H1 you're trying to base their position off of.

The easiest way to do this would be dropping the HTML responsible for this ribbon ends within the H1. This, however, is not semantically the best. You could add a wrapper around the ribbon ends AND the H1, but that's extra markup.

By using :after and :before, you're using the H1 as the parent since it has a position of relative, and absolutely positioning the pseudo :before and :after elements relative to that H1. This is ideal since the pseudo elements can now inherit things like the height, background color, etc.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top