css overflow hidden increases height of container
Asked Answered
V

4

45

Please have a look at this fiddle - http://jsfiddle.net/Z27hC/

var container = document.createElement('span');
container.style.display = 'inline-block';
container.style.marginTop = '10px';
container.style.marginLeft = '50px';
container.style.background = 'lightblue';
document.body.appendChild(container);

var cell = document.createElement('span');
cell.style.display = 'inline-block';
cell.style.border = ' 2px solid black';
cell.style.width = '200px';
cell.style.height = '16px';
cell.style.overflow = 'hidden';
container.appendChild(cell);

var text_node = document.createTextNode('hallo');
cell.appendChild(text_node);

I have a container, containing a cell, containing a text node. The cell has a fixed width.

If the text passed to the text node exceeds the width, I want it to be truncated, so I set the cell to 'overflow: hidden'.

It works, but it causes the height of the cell to increase by 3px. The cell has a border, but the increased height appears below the border, not inside it.

As I have many cells in a spreadsheet style, it messes up the layout.

I have tested this on IE8 and Chrome, with the same result.

Any of the following solutions would be ok -

  • prevent the increased height from occurring
  • keep the increased height inside the border
  • another way to truncate the text

As requested, here is a new fiddle that shows a more complete example.

http://jsfiddle.net/frankmillman/fA3wy/

I hope it is self-explanatory. Let me know if you need anything explained in more detail.

Here is (hopefully) my final fiddle -

http://jsfiddle.net/frankmillman/RZQQ8/

It incorporates ideas from all responders, and it now works as I want.

There are two main changes.

The first one was inspired by Mathias' table solution. Instead of an intermediate container, containing a blank row and a data row, one of which was hidden and one shown, I now just have alternating blank and data rows in the top-level container. I don't think it affected my layout problem, but it cut out a layer and simplified the code.

The second change, suggested by all the responders, actually fixed the problem. Instead of having elements of type 'span' with display 'inline-block', I now use 'div', and a careful mix of 'float left' and 'float right' to achieve the layout I want.

Many thanks to all.

Venetic answered 15/3, 2014 at 9:7 Comment(6)
Thanks for the replies, Mathias and Niles. Your suggestions work with my simple example, but my actual program has several more layers, and they do not work perfectly there. I will continue investigating, and report back.Venetic
Can you put together an example that shows what issues with your full layout. Just the HTML and CSS.Hoashis
Not sure of the correct etiquette here, but I have edited my original post and added a new fiddle with a more complete example.Venetic
Have you considered using a table? It just seems like you are creating a table jsfiddle.net/borglinm/fA3wy/3Hoashis
Thanks, Mathias. I appreciate the time and trouble you took to come up with that. I did not use it in the end, but it pointed me in the right direction. I have attached a new fiddle that now works the way I want.Venetic
You might want to consider moving the final solution into an answer below instead of here, since it solves your problem.Gleesome
E
46

Let me explain to you why this is happening.

According to CSS 2.1 Specs,

The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge.

To explain in simple words,

i) If inline-block in question has its overflow property set to visible (which is by default so no need to set though). Then its baseline would be the baseline of the containing block of the line. ii) If inline-block in question has its overflow property set to OTHER THAN visible. Then its bottom margin would be on the baseline of the line of containing box.

So, in your case the inline-block cell has overflow:hidden (not VISIBLE), so its margin-bottom, the border of cell is at the baseline of the container element container.

That is why the element cell looks pushed upwards and the height of container appears increased. You can avoid that by setting cell to display:block.

Estrada answered 15/3, 2014 at 15:17 Comment(3)
Thanks for the explanation. As suggested by @Niles I tried 'display:block' and it worked for my simple example. Unfortunately it does not work in the more complete example I have just posted. Sometimes a cell contains more than one element. If I change'inline-block' to 'block' they are laid out vertically instead of horizontally.Venetic
But if you use display:block, it will take up the entire line. You can't just switch from 'inline-block' to 'block' like this. If it has a fixed-width, yes, but otherwise, this simply will not work. This problem is NOT solved.Mealtime
This might help: #20311190Alcinia
P
46

The overflow-property can change the baseline of an element. To prevent this you can use vertical-align on inline-blocks.

cell.style.display = 'inline-block';
cell.style.overflow = 'hidden';
cell.style.verticalAlign = 'bottom';

http://jsfiddle.net/23e0rny9/

Pantheon answered 25/5, 2016 at 3:38 Comment(4)
vertical-align: top; seems to work better as suggested by #20311190Sabah
vertical-align: sub; worked for me. top and bottom did not. I'm not sure why. Once this answer got me close, I just started trying things.Pushup
Here's the full example: trade-ideas.com/home/phil/Triangles/HeapSort.html You can search the source for "vertical-align" or look for the right moving arrows if you're running the program.Pushup
This worked best, as changing display: block messes up your positions of elements following the element in question.Rogan
H
5

Try setting line-height: 0 for the container and line-height: 20pxfor your cells

container.style.lineHeight = '0px';

cell.style.lineHeight = '20px';

Fiddle

Or you can use float: left on your cells

cell.style.float = 'left';

Fiddle2

Hoashis answered 15/3, 2014 at 9:20 Comment(0)
S
1

use the dsiplay 'block' of cell

cell.style.display = 'block';

and

cell.style.float= 'left';

to align left if you want to align

Snuggery answered 15/3, 2014 at 9:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.