Pure HTML / CSS solution for aligning 3 elements, when 2 have dynamic size?

This question needs a little explanation. Please feel free to:

A few months ago, I created a three-part heading for a section on a website. On the left side of this heading is a Heading, the contents of which may change. On the right side is the logo, which will always have a width of 150 pixels and a height of 60 pixels. Between them there is a set of double lines. Something like that:

[THIS TITLE] ====================================== [Logo Here]

This site is responsive, so the overall width of the header is variable.
The title should always be on the same line. In order to fill the gap between the title and the logo, the div holding the double lines must be resized.

I initially set it up so that the lines change using media queries and calc (); function. However, the website should be fully compatible with IE 8, so I wrote some JS to get it working.

Here is a JS fiddle that essentially reflects 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 problem is that the script takes a long time to load slow connections, and therefore the logo hangs in a strange place for some time. As a result, I try to find a purely CSS / HTML solution to do the same thing as my script.

There are related questions here, but none of them seem to apply. I can’t put the width in either the header or the lines, because they are both dynamic.

The tables seem to work fine, but if I set width: auto; on two of tds, everything fails.

Here is an example of a suitable table layout that I 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 tried to put the position: absolute; and top / left or top / right logo and title, but I can’t get this middle div to resize correctly.

So: if someone did this here: Any ideas on how I can get this to work without JS? Or maybe a way to remove my JS so that it works faster?

Thanks!

+5
source share
3 answers

Your problem can be completely solved using HTML and CSS, changing them slightly, and JavaScript is not needed.

Here is my fork Danield fiddle - Support IE8 +

Explanation:

  • Moving #the-logo to be the first element in the #entire-Header container allows us to float #the-logo to the right, without wrapping it and removing it under the heading, because it has a “higher priority” when the layout is calculated.

  • Adding "clearfix" to #entire-Header allows us not to worry about the header overflowing the space allocated by fixed sizes. This frees us to completely remove the height constraint. #entire-Header is an element of the block level ( div ), which means that by default the width will be 100% and does not have to be explicitly set (if it has not been previously redefined).

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

  • Now that we have the logo and name located on both sides, we can style the #the-lines . Being an element of the block level, it will expand horizontally into the available space, which in this case is 100%. So that it does not extend below the name and logo, add overflow: hidden or overflow: auto to #the-lines . This creates a new formatting block that makes the #the-lines width narrow until the remaining available space, which is calculated between two floating elements.

    Caution:. This will only work as long as the #the-line height is less than the #the-logo height, otherwise #the-line will wrap below #the-logo . This is because it is the third element, and the first two elements affect its layout.

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; } 

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> 
+1
source

IE8 support

If you want to keep supporting IE8, you can fix the slow loading by including the <script> in the HTML.

  ... </div> </div> <script> // JavaScript here </script> </body> 

No IE8 support (IE10 +)

If you want to use a clean CSS solution, use flexbox. Create a flexbox header, assign an order to the header, line and logo and let the line shrink and grow as needed.

 <!-- HTML --> <div class="container"> <div class="title"> Title </div> <div class="line"> Line </div> <div class="logo"> Logo </div> </div> 

 /* CSS */ .container { display: flex; width: 100%; } .line { order: 1; flex-shrink: 10000000; flex-grow: 10000000; } .title { order: 0; flex-shrink: 1; } .logo { order: 2; flex-shrink: 1; } 

For more information on flexbox, see this article and this useful flexbox playground .

0
source

It can be done with IE8 support.

1) Move fixed width + floating right image as first child

2) Keep float:left in the title

3) Set overflow:hidden (or auto) in the lines (to set a new block formatting format)

4) Set display:inline-block to the container (to contain floats)

Updated FIDDLE (resize browser to see effect)

 #entire-Header { display: inline-block; width: 100%; height: 40px; } #the-h2-Title { float: left; padding-right: 10px; } #the-lines { border-top: 4px solid #000000 !important; border-bottom: 4px solid #000000 !important; height: 1px; overflow: hidden; margin-top: 23px; } #the-logo { width: 160px; height: 50px; padding-left: 10px; float: right; } 
 <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> 
0
source

All Articles