Vertical gaps resulting from nested inline block elements inside DIV containers – I

In the course of a series of articles about Responsive Web Design I made use of some elements in a horizontal menu line in the form of “inline block elements”. See:
Responsive fluid multi-column layouts – main menu control with JS/jQuery and font-size adaption – V
and other articles quoted there.

One reason for using inline elements was/is that the centering of inline blocks without a defined width inside a DIV block container is easy. One may need this e.g. in templates for a CMS where you do not know the number and the text of menu points in advance.

When my wife recently started building a new website for a customer she used part of my prescriptions and came back with an annoying finding:

If you embed and nest inline block elements inside standard block DIV containers and define

  • both the container and its inline block elements to have some (min-) heights
  • and define in addition for each of the (nested) inline elements a line-height

then FF (better the Gecko engine) will create some vertical pixels distance – a gap – between the bottom of the DIV-container and its enclosed inline block element(s) and/or between the lower borders of nested inline block elements. This happens when

  • the heights of all nested elements (blocks, inline blocks) are not defined exactly
  • AND no innermost real inline element (as a text) with a precisely defined height can be found.

The vertical gaps are an interesting though counter-intuitive consequence of the application of CSS2/3 rules. You may by accident stumble across similar effects when working with nested inline blocks. So, I thought it may be interesting to write a bit about it – and discuss some precautions and remedies in case you need to deal with unexpected vertical element gaps.

Why use undefined DIV container and undefined (inline) block heights?

Why would we use nested block or inline-block elements without a precise height definitions? Well, in some contexts and especially when we design responsive layouts for mobiles we may need vertical flexibility. One example is the creation of flexible menus in templates for CM-systems: To make them generally applicable one cannot make assumptions on the specific size/length of the menu point texts. We do not know whether line wrapping will occur and how much the container of a menu element will have to extend its vertical height.

In such a case min-height style definitions are required instead of precise “height”-definitions. Additional “line-height” definitions may be required

  • to vertically center text in standard cases with the text fitting into a one line geometry
  • and/or to control the vertical space requirement when line wrapping occurs.

Vertical height control is simple when you work with standard block elements – it is the standard box model that defines everything. However, some surprising things may occur when we deal with (nested) inline blocks with defined line-heights.

A simple example for nested inline blocks with unexpected vertical gaps

Just to get an example for the occurence of vertical gaps associated with inline block elements let us have a look at the following simple HTML code:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Test</title>
<style type="text/css">
	

	html {
		font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
		font-size: 10px;
	}
	
	div {
		position:relative;
		margin:0;
		padding:0;
	}
	
	div.header {
		float:left; 
		width: 30.0rem; 
		min-height: 3.2rem; 
		background-color: #DDDDDD;
	}
	
	div.hornav {
		width: auto; 
		min-height: 3.0rem;
		line-height:0;
		line-height: 3.0rem;
		border: #F00 0.1rem solid;
		background-color: black; 
		text-align: center; 
		
	}
	
	div.hornav_txt {
		display:inline-block; 
		width: 20.0rem;  
		min-height:2.8rem;
		line-height:0;
		line-height: 2.8rem;
		border: solid 0.1rem #FF0; 
		background-color: #FFF;
		text-align:center; 
		
	}
	
	div.mp_cont {
		display:inline-block; 
		width:10.0rem; 
		min-height:2.6rem;
		line-height:0;
		line-height:2.6rem; 
		border:solid 0.1rem #090;
		background-color:#F00; 
		
	}
	
	div.bg{
		position: absolute; 
		width:10.0rem; 
		min-height:2.6rem;
		line-height:0;
		line-height:2.6rem; 
		top:0;
		bottom:0;
		left:0;
		right:0;
		border:0;
		background-color:#FF0;
		opacity: 0.5;
		z-index:1;  
	}
	
	div.fg {
		position: relative; 
		width:10.0rem; 
		min-height:2.6rem;
		line-height:0;
		line-height:2.6rem; 
		border:0;
		z-index:2;
	}
	
</style>
</head>

<body>
   <div class="header">
       <div class="hornav">
           <div class="hornav_txt">
               <div class="mp_cont">
                   <div class="bg"></div>
                   <div class="fg"></div>
                </div>
           </div>
       </div>
    </div> 
</body>
</html>

 
When we open a HTML file with the above contents in a present Firefox version (41.x) for Linux or e.g. the browser built into Eclipse we get the following picture (the KDE lineal on the right side was added for pixel measurement).

inline_blck2

We see that our horizontal centering works perfectly – however, regarding the heights we get a weird vertical gap of a size around 8 to 10 pixels. This seems to be wrong – at least compared with (naive) expectations based on the CSS definitions given above: all min-heights plus border dimensions were chosen with values such that all nested elements should vertically fit into each other seamlessly.

What exactly did we do in our example?

We defined an outer container DIV “div.header” which works like a kind of header section. Inside we placed a new standard block container “div.hornav”. Let us look at it as a frame for an expandable menu. Then we placed and horizontally centered an inline block element “div.hornav_txt” inside our “div.hornav”. This inline block element shall work as the container of a menu point. A menu point itself “div.mp_cont” then contains 2 absolutely positioned layers over each other. This allows for the opacity control of the background-color and a menu text with no opacity (opacity:1.0). All containers have only defined min-heights – but as long as the menu text uses only one line all elements should fit perfectly into each other (including borders).

So why does the obvious visible vertical distance occur at all?

A plausible reason for the vertical gaps

Our intuition for a seamless vertical fitting is based on 2 assumptions, namely

  • that an inline-block would behave more or less like a standard block element,
  • and that a surrounding block would adjust to an encapsulated inline block as if the latter were a block element.

Both assumptions are wrong. To understand a bit better what happens let us first look at how the height of a block DIV container responds to its contents if no precise height value is defined:

The browser will analyze the required height of the block contents and adjust the block height according to the box model with paddings and margins (if defined). In case the encapsulated contents is an inline element – as e.g. a text – then its space requirements is analyzed – e.g. the font-size plus required space above and below to account for all types of letters of this font – e.g. “&Uuml”; or “j”. If you artificially reduce the line-height of the contents and the encapsulating box vertical below the height required for a full display of the font letters vertical overlaps of the several text lines may occur and the box size will shrink to defined limits related to the font size according to CSS rules.

E.g.:

	<div style="clear:left; width: 20.0rem; margin-top:150px; line-height:0.0rem; background-color: yellow;">
		<span style="font-size:8.8rem; line-height:0.0rem; ">ÜJ<br>jÜ</span>
	</div>

 
leads to:
nested_inline_blocks_2

In contrast

	<div style="clear:left; width: 20.0rem; margin-top:150px; line-height:0.0rem; background-color: yellow;">
		<span style="font-size:8.8rem; line-height:0.0rem; ">ÜJ<br>jÜ</span>
	</div>

 
leads to:
nested_inline_blocks_3

So far, so good. In any case: What happens exactly depends on the (inline) contents, its height and the line-height calculated or defined for the display of the contents.

Now back to our example:

As there is no container element with a defined height the browser engine has to analyze successively nested inner elements to determine defined or calculable height scales. But in our case we never get to such a finite height scale for the relatively positioned elements inside the innermost inline block container.

The only precisely defined height scale in our example is eventually given by a letter “x” – however, the height of this letter only affects layers absolutely positioned at z-indices above their containers. It has no impact on the sizing of the container “div.mp_cont”.

So what can the browser engine actually cling to and rely on when following the successively embedded and relatively positioned elements? The last height scales given is the min-height and the line-height of the innermost inline (!) block element div#mp_cont. But from the perspective of the surrounding encapsulating containers “div.hornav_txt” and “div.hornav” this actually has the same effect as if a big letter had been placed inside them.

By using a small trick we can actually see that our FF browser engine (Gecko; but KHTML/Webkit does it as well) adjusts the baseline for letters according to this pseudo-“letter”-dimension (i.e. according to the height of the inline box “div.mp_cont”)
and reserves vertical space in between the two successive inline-block elements.

<body>
        <div class="header">
            <div class="hornav">
                <div class="hornav_txt" style="line-height:0;">
                	<div class="mp_cont">
                		<div class="bg"></div>
                		<div class="fg">x</div>
                	</div>
             	</div>
			</div>
        </div> 
        <div class="header" style="margin-left:50px;">
            <div class="hornav">
                <div class="hornav_txt">
                	<div class="mp_cont">
                		<div class="bg"></div>
                		<div class="fg"></div>
                	</div><span style="font-size:2.8rem; ">XÜj</span>jjgg
             	</div><span style="color:yellow;">jg</span>
			</div>
        </div>
</body>

 
results in :

nested_inline_blocks_4

So, indeed: If we add some normal letters we see that the baseline for letters inside “div.hornav_txt” is the bottom of the included “div.mp_cont”. But letters require additional vertical space below their baseline!

So, the browser recognizes the existence of some inline (!) contents with a defined (min-) height inside the first inline-block “div.hornav_txt” and adjusts everything else according to some complicated height calculations. See http://www.w3.org/TR/CSS21/visudet.html#propdef-line-height.

I have to admit that I do not really understand all details and their consequences of the W3C height calculation rules. But the overall effect of nesting an inline block with a min-height inside another inline block without any further defined (inner) height scale resembles pretty much a situation in which a letter with the same font-height value were placed inside the enclosing outer inline block (here inside “div.hornav_txt”).

Conclusion: In the absence of any further inline element with precisely defined height the min-height of the innermost identifiable inline element determines the full layout and the resulting height calculations

  • for any surrounding (inline) block elements with flexible height
  • and then the innermost relatively positioned standard block container enclosing the nested inline blocks

just as a letter with the same font-size would do. And a letter needs more vertical space then its font-size! The nested inline blocks transfer the resulting excess height requirement to the enclosing standard block element and therefore automatically lead to a vertical gap! (I suspect that the size of the gap depends on the rendering engine of the browser, but it did not investigate this point, yet).

Note: This may also happen inside horizontal lists where inline blocks are used instead of floated elements.

In the next article

Vertical gaps resulting from nested inline block elements inside DIV containers – II – getting control

we shall play around with our example and show what happens if
we change the innermost contents and/or some CSS settings. Our objective then is to get control over the vertical gaps introduced by the rendering engine.

Linux – Dell U2515H – questions regarding KDE adjustments and older graphics cards

Some months ago I wrote 2 blog articles about the use of (multiple) DELL U2515H screens on a Nvidia GTX750 TI graphics card on a Linux system.

Linux – Nvidia GTX 750 TI – Parallelbetrieb von 2 Dell U2515H mit 2560×1440 plus einem 1920×1200 Schirm
Linux – Nvidia GTX 750 TI – Dell U2515H – HDMI – 2560×1440 Pixel

Last week a reader, who had found these blog articles, asked me the following:

I am currently using a Dell U2412m with 1920×1200 resolution but I am planning to upgrade to a 2560×1440 and thought about the U2515H but I am a bit worried about how Plasma shows on such a high dpi panel. Do you have any issue with interface elements which are showed too small and are not tuneable?

Second thing I am a bit worried of my GTS 450 performance but I will upgrade my video card after the new nVidia series is launched.

I found these questions interesting and present my answers in form of this blog contribution.

Warning statement regarding older graphics cards

Before I get to the question regarding KDE and a high resolution screen as the DELL U2515H I want to make a warning statement:

The graphics card you want to use together with a Dell U2515H and the graphics card drivers MUST support high resolution HDMI (vers. 1.4, 2.0) or display port connections. Reason: The Dell U2515 does NOT provide any DVI connections!

Do not underestimate this topic for older graphics cards! Actually, I had very bad experiences in the past with a GTX 460 which provides a mini HDMI port: I never got a high resolution HDMI connection to run with this card (not under Opensuse 13.1/13.2). Despite high quality cables and in contrast to another system with a GTX 750 TI. And I really tried a lot of settings and driver versions until I gave up.

And note: Even the GTX 750TI required some effort and fiddling – but eventually it worked. This is the reason why I wrote about it.

So, if you have some money and want to avoid frustration with the DELL U2515H, I would suggest to buy a reasonable modern card which offers support for (several) display ports and/or high resolution HDMI. If gaming under Linux is not a topic (as in my case) but still some 3D applications or CUDA floating point operations are part of your work then presently a GTX 960 or the GTX 750 could be a reasonable alternative regarding the price-value relation. But look out for the number of ports supported – especially if you want to use several screens.

KDE and high resolution screens in general

It is quite clear that a screen resolution of 2560×1440 will significantly reduce the visible size of fonts and desktop elements scaled with font size. So, what you need is a very flexible scalability of fonts both for the desktop and window control elements as well as for applications you use.

The question whether Linux desktops as KDE are prepared for high resolution screens was also posed in an article with the title “Skaliert” (Scaled) published in the German “linuxuser” 10/2015. See http://www.linux-community.de/Internal/Artikel/Print-Artikel/LinuxUser/2015/10/Skaliert. Unfortunately, this article costs money to read it online. Actually, relatively small problems were described for KDE. This is very consistent with my own experience with both KDE 4.14 and KDE 5.x.

You can adjust almost all required basic font settings for the KDE desktop via KDE’s “systemsettings” and in addition most
applications offer scrollable and relatively seamless font scaling (e.g. via mouse scrolling). Playing around with font smoothing plus an enforcement of dpi resolution may pay off in case you care for smooth font displaying. (Actually I never had to apply any special contrast settings of the screen itself beyond standards for the screen to get a clear, but nevertheless smooth font display).

The spectrum of applications I primarily use consists of a mixture of QT and GTK applications:

KDE konsole and other terminal emulations, different types of graphical KDE file editors, different types of browsers (primarily FF and chromium), libreoffice, eclipse mars, aptana studio, SVN frontends, crossover with ms office applications, vmware with different types of guests, kvm with different types of guests, sound and multimedia applications, blender, etc., etc.

Almost all of my favorite applications offer internal font adjustment capabilities and the typical graphical elements of these applications scale seamlessly with font size. So, no reason to worry about KDE and its plasma desktop: In my opinion KDE is well prepared for high resolution screens.

A problem may, however, be the smooth integration of some GTK applications (as e.g. eclipse) into high resolution KDE, which is based on QT – but also there you have sufficient options with different GTK themes – and most of the problems I had were independent of the screen resolution and more GTK theme dependent. You may have to play around a bit with KDE’s settings for GTK integration – especially with the choice of the GTK design or GTK theme.

KDE and screens with different resolutions

A real problem in my opinion may result from a mixture of 2 screens with different (!) native resolutions. There is no way known to me to apply different font-settings to different screens on a KDE desktop comprising several screens in form of a Nvidia Xinerama combination.

As long as I used 2 screens – one with a resolution of 1920×1200 and one with 2560×1440 – I really suffered a bit from the display discrepancies regarding font size. Especially when I wanted to open several windows of one and the same application – as 2 windows of Eclipse – on both screens or whenever I wanted to stretch one application (e.g. VMware) over the 2 screens. You may try to find compromises – but it will never be perfect.

However, in my present daily work with 3 screens – 2 with 2560×1440 and 1 with 1920×1200 – the different display of font sizes may become even an advantage: Just by moving an application to the lower resolution screen you get a better view on details. (But I admit, this is pure luxury, not only for development work.)

Nevertheless it would be fun if KDE in the future could provide a possibility to adjust font-sizes per screen in a Xinerama version.

Performance?

I do not know exactly how a GTS 450 graphics card performs. But my guess is that even for 2 screens (with 2560×1440) performance for the simple 3D effects of a plasma desktop should be no topic at all – even for this card. Actually, it is really frustrating that you cannot use high resolution HDMI with older graphics cards – despite the fact that the graphics card may support a combined resolution of 2 x 2560×1440 for DVI capable screens and provide a sufficient performance for it.

I should, however, mention that for three screens (2 x 2560×1440, 1x 1920×1200) my GTX 750 TI works constantly with high frequencies of both CPU and memory. The card never reduces this frequencies during normal use – so it will consume more electrical power than in a 2 screen situation. For 2 screens at 2560×1440 it always reduced frequencies to lower levels when only 2D applications were used on the desktop. However, despite constant high frequencies I never noticed any heat problem under normal conditions. The ventilators operate at basic speed and temperatures are between 36 and 40 &
deg; Celsius.

With high resolution 3D games you may have a different experience – but if I play (which is seldom) I never play with extreme resolutions. So, actually I do not know how high resolution games perform on a (3D) KDE desktop.

Summary

Regarding the use of KDE with the DELL U2515H in my opinion you need not worry about font scalability and performance. You should worry more about the support of high resolution HDMI and display ports by both the physical card and the drivers for older Nvidia cards. A combination of a DELL U2515H with a screen of lower resolution will lead to problems – as visible font sizes may differ significantly.

Remark, added 17.12.2015:
Meanwhile I had the chance to test a Nvidia GTX 960 from Gigabyte together with 2 DELL U2515H connected via display port and a 1920×1200 screen connected via DVI. Works without any problems. And I see no problems with native Linux 3D OpenGL games as Red Eclipse or Xonotic at high resolutions so far. Temperatures around 43° Celsius.