Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pure HTML/CSS solution for aligning 3 elements when 2 are dynamically sized?

This question takes a bit of explaining. Please bear with me:

A few months ago, I set up a three-part header for a section on a website. On the left side of this header there is a Title, the contents of which can change. To the right side is a Logo, which will always be 150 px wide by 60 px high. Between them are a set of double lines. Something like this:

[THIS IS THE TITLE] ======================================= [Logo Here]

This website is responsive, so the overall width of the header is variable.
The Headline must always be on one line. The div holding the double lines needs to change size to fill the space between the Title and the Logo.

I initially set it up so that the lines resized using media queries and the calc(); function. However, the website has to be compatible all the way down to IE 8, so I ended up writing some JS to get it to work.

Here is a JS fiddle that's essentially mirroring this behavior: http://jsfiddle.net/55u5mpu2/2/

function sizeLines() { 
var logoSize = document.getElementById("the-logo").offsetWidth; 
var titleWidth = document.getElementById("the-h2-Title").offsetWidth; 
var totalWidth = document.getElementById("entire-Header").offsetWidth; 
var offsetWidth = (logoSize + titleWidth); 
var linesWidth = (totalWidth - offsetWidth - 20) + "px"; 
document.querySelector("#the-lines").style.width = linesWidth;   }

window.onresize = sizeLines; 
#entire-Header{
  position: relative;
  width: 100%;
  height:40px;
}

#the-h2-Title {
  position: relative;
  float: left;
  width: auto;
    padding-right: 10px;
}

#the-lines {
  border-top: 4px solid #000000 !important;
  border-bottom: 4px solid #000000 !important;
  height: 1px;
  float: left;
  margin-top: 23px;
  min-width: 40px;
}

#the-logo {
  position: relative;
  max-width: 160px;
  max-height: 50px;
  float: right;
  width: auto;
  height: auto;
  top: 0;
}
<div id="entire-Header">
   <h2 id="the-h2-Title">
      <div id="headlineTextbox">This is a Test Headline</div>
   </h2>
   <div id="the-lines"> &nbsp;</div>
   <img id="the-logo" src="http://placehold.it/150x60">
</div>

The issue is, the script takes a long time to load on slow connections, and so the logo is hanging out in a weird spot for a while. As a result, I'm trying to find a purely CSS/HTML solution to do the same thing that my script is.

There are related questions here, but none of them seems to apply. I can't put a width on either the title or the lines, because they're both dynamic.

Tables seem to be working okay, but if I put width: auto; on two of the tds, things fail.

Here's an example of an okay table layout I've created: http://jsfiddle.net/d40a429s/1/

table {width: 100%;}
#test-title {width:20%;}
#lines-here {width:auto;}
#lines-here > div {border-top:4px solid #2a2a2a; border-bottom:4px solid #2a2a2a;height: 1px;}
#test-logo {width: 160px; padding-left: 10px;}
<div id="test-Section-Header">
   <table>
      <tbody>
         <tr>
             <td id="test-title"><h2>Test Title</h2></td>
            <td id="lines-here">
               <div></div>
            </td>
            <td id="test-logo">
               <img src="http://placehold.it/150x60" alt="150 x 60 placeholder logo image">
            </td>
         </tr>
      </tbody>
   </table>
</div>

I've tried putting position: absolute; and a top/left or top/right on the logo and title, but I can't get that middle div to resize properly.

So: if anyone made it down here: Any ideas on how I can get this to work without JS? Or maybe a way to tidy up my JS to make it run faster?

Thanks!

like image 469
not_rosie_the_riveter Avatar asked Nov 10 '22 15:11

not_rosie_the_riveter


1 Answers

Your problem can be solved entirely using HTML and CSS by modifying them both slightly, no need for JavaScript.

Here is my fork of Danield's fiddle - Supports IE8+

Explanation:

  • Moving #the-logo to be the first element within the #entire-Header container allows us to float #the-logo right, without it wrapping and dropping below the title because it has a "higher priority" when the layout is being calculated.

  • Adding a "clearfix" to #entire-Header allows us to not be concerned about the title overflowing the space that is allocated by any fixed dimensions. This frees us up to remove the height constraint altogether. #entire-Header is a block level element (div) which means that by default it's width will be 100% and doesn't need to be explicitly set (unless it has previously been overridden).

  • #the-h2-Title is the second element within #entire-Header and is floated left. Being a block element (h2), it will wrap below #the-logo as a whole before wrapping the words within itself.

  • Now that we have the logo and the title positioned on either side, we can style #the-lines. Being a block level element, it will expand horizontally into the available space, which in this case is 100%. To prevent it from extending below the title and the logo, we add overflow: hidden or overflow: auto to #the-lines. This creates a new block formatting context which makes #the-lines's width narrow to the remaining available space which is calculated between the two floated elements.

    Caveat: This will only work as long as the height of #the-line is less than that of #the-logo, otherwise #the-line will wrap below #the-logo. This is because it is the third element and it's layout is affected by the first two elements.

The CSS:

#entire-Header {
    margin: 1em 0 .5em;
}
/* http://nicolasgallagher.com/micro-clearfix-hack/ */
#entire-Header:before,
#entire-Header:after {
    content: " ";
    display: table;
}
#entire-Header:after {
    clear: both;
} 
#the-h2-Title {
    margin: .5em 0;
    float: left;
    margin-right: 10px;
}
#the-lines {
    border-top: 4px solid #000000 !important;
    border-bottom: 4px solid #000000 !important;
    height: 1px;
    /* http://www.stubbornella.org/content/2009/07/23/overflow-a-secret-benefit/ */
    overflow: hidden;
    margin-top: 23px;
}
#the-logo {
    width: 160px;
    height: 50px;
    margin-left: 10px;
    float: right;
}

The Markup:

<div id="entire-Header">
    <img id="the-logo" src="http://placehold.it/150x60" />
     <h2 id="the-h2-Title">
      <div id="headlineTextbox">This is a Test Headline</div>
   </h2>

    <div id="the-lines"></div>
</div>
like image 89
mrkiffie Avatar answered Nov 15 '22 06:11

mrkiffie