JimmyBoy
JimmyBoy

Reputation: 369

css element border influence on other elements in a weird way

I am having a weird thing I am failing to understand the cause. I have created a fiddle to demonstrate the issue.

what I am failing to understand is why setting a border to one of the three canvases makes my two other .headerMainDiv go down from their original position (try to play with the border's size / delete the border and see the effect).

here is the relevant part of my html:

<header>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas1">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas2">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">
        <div class="inner">         
            <canvas id="canvas3">

            </canvas>   
        </div>      
    </div>
</header>

and here is the relevant css:

#canvas2{
  border:10px solid black;
}

.inner {
  margin-top: 2px;
}

.headerMainDiv {
  height: 100%;
  width: 30%;
  background-color:red;
}

body{
  margin: 0;        
}

header{
  height: 20%;
  width: 100%;
  top:0px;
  text-align: center;
  position: fixed;
  z-index: 5;
  background-color: blue;
}

header div {
  display: inline-block;
}

canvas {
  background-color: grey;
  width:100%;
  height:100%;
}

I am not looking for a solution to my problem but for an explanation to this "problem/ behavior".

Thanks a lot. Jimmyboy.

Upvotes: 1

Views: 1088

Answers (5)

Paulie_D
Paulie_D

Reputation: 114991

what I am failing to understand is why setting a border to one of the three canvases makes my two other .headerMainDiv go down from their original position (try to play with the border's size / delete the border and see the effect).

The issue I think you are referring to is the vertical alignment that is, be default, set to baseline for inline block elements...which wrap your canvas elements.

All you really need to do is set:

header div {
    display: inline-block;
    vertical-align: top;
}

JSfiddle Demo

That said, using border-box is probably a good default option so I have included it in the demo.

Upvotes: 2

Ori Drori
Ori Drori

Reputation: 191946

It's because the borders increase the width of the element. Using box-sizing: border-box would include the borders in the overall width of the element.

Adding display: inline-block; vertical-align: top; to .headerMainDiv should solve the alignment problem - updated fiddle.

canvas {
    box-sizing: border-box;
    background-color: grey;
    width:100%;
    height:100%;
}

.headerMainDiv {
    display: inline-block;
    vertical-align: top;
    height: 100%;
    width: 30%;
    background-color:red;
}

Upvotes: 0

chillvivek
chillvivek

Reputation: 310

It is because you have used display as inline-block. The vertical-align property is inherited as baseline. That is the reason you see all the divs aligned to the floor of parent div.

enter image description here

Upvotes: 2

Terry
Terry

Reputation: 66103

That is because you have declared a 100% width on your canvas element, and added borders on top of that. This causes the width to exceed 100%, resulting in an overflow.

What you could do is to force the browser to compute the border width(s) as part of the width declaration. This can be done by using box-sizing: border-box on your canvas elements:

#canvas2{
  border:10px solid black;
}

.inner {
  margin-top: 2px;
}

.headerMainDiv {
  height: 100%;
  width: 30%;
  background-color:red;
}

body{
  margin: 0;        
}

header{
  height: 20%;
  width: 100%;
  top:0px;
  text-align: center;
  position: fixed;
  z-index: 5;
  background-color: blue;
}

header div {
  display: inline-block;
}

canvas {
  box-sizing: border-box; /* Force border widths to be part of declared width */
  background-color: grey;
  width:100%;
  height:100%;
}
<header>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas1">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas2">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">
        <div class="inner">         
            <canvas id="canvas3">

            </canvas>   
        </div>      
    </div>
</header>

However, if you want to make all the divs appear to be the same height, you will need to make sure that the extra border height in the second canvas is also added to those canvases without borders, by:

  1. Using top and bottom transparent borders
  2. Using top and bottom margins on the first and third canvas
  3. Using top and bottom paddings on the parent element of the first and third canvas

Here is a solution using the first solution:

#canvas1, #canvas3 {
  border: 10px solid transparent;
}
#canvas2{
  border: 10px solid black;
}
.inner {
  margin-top: 2px;
}

.headerMainDiv {
  height: 100%;
  width: 30%;
  background-color:red;
}

body{
  margin: 0;        
}

header{
  height: 20%;
  width: 100%;
  top:0px;
  text-align: center;
  position: fixed;
  z-index: 5;
  background-color: blue;
}

header div {
  display: inline-block;
}

canvas {
  box-sizing: border-box; /* Force border widths to be part of declared width */
  background-color: grey;
  width:100%;
  height:100%;
}
<header>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas1">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">         
        <div class="inner">         
            <canvas id="canvas2">

            </canvas>   
        </div>      
    </div>
    <div class="headerMainDiv">
        <div class="inner">         
            <canvas id="canvas3">

            </canvas>   
        </div>      
    </div>
</header>

Upvotes: 1

Marcos P&#233;rez Gude
Marcos P&#233;rez Gude

Reputation: 22158

If you need that border doesn't affects to the width of your box, you need to specify box-sizing property.

   #canvas2{
      border:10px solid black;
      box-sizing:border-box;
   }

Box sizing setting to border-box avoid the paddings and the borders without affecting to your width. Check this out

http://jsfiddle.net/d6tukcdz/6/

If it's not your problem, please, explain better

Upvotes: 1

Related Questions