xRobot
xRobot

Reputation: 26567

Multiple HTML elements with percentage width

I am trying to build a very simple timeline with only HTML and CSS.

This is my code:

.timebox {
  float: left;
  height: 2px;
  background: #7D80E6;
  position:absolute;
}

.timeboxhour {
  width: 4.16%;
  float: left;
  height: 2px;
  background: #eee;
  color: #666;
  font-size: 0.8em;
  text-align: left;
}
<div id="timeline" style="background: #fff;width: 100%;height: 2px;margin: 0 auto;">
<div class="timebox" style="margin-left:0%;width:1.04%;"></div>
<div class="timebox" style="margin-left:4.16%;width:1.04%;"></div>
<div class="timebox" style="margin-left:8.32%;width:1.04%;"></div>
<div class="timebox" style="margin-left:12.48%;width:1.04%;"></div>
<div class="timebox" style="margin-left:16.64%;width:1.04%;"></div>
<div class="timebox" style="margin-left:20.8%;width:1.04%;"></div>
<div class="timebox" style="margin-left:24.96%;width:1.04%;"></div>
<div class="timebox" style="margin-left:29.12%;width:1.04%;"></div>
<div class="timebox" style="margin-left:33.28%;width:1.04%;"></div>
<div class="timebox" style="margin-left:37.44%;width:1.04%;"></div>
<div class="timebox" style="margin-left:41.6%;width:1.04%;"></div>
<div class="timebox" style="margin-left:45.76%;width:1.04%;"></div>
<div class="timebox" style="margin-left:49.92%;width:1.04%;"></div>
<div class="timebox" style="margin-left:54.08%;width:1.04%;"></div>
<div class="timebox" style="margin-left:58.24%;width:1.04%;"></div>
<div class="timebox" style="margin-left:62.4%;width:1.04%;"></div>
<div class="timebox" style="margin-left:66.56%;width:1.04%;"></div>
<div class="timebox" style="margin-left:70.72%;width:1.04%;"></div>
<div class="timebox" style="margin-left:74.88%;width:1.04%;"></div>
<div class="timebox" style="margin-left:79.04%;width:1.04%;"></div>
<div class="timebox" style="margin-left:83.2%;width:1.04%;"></div>
<div class="timebox" style="margin-left:87.36%;width:1.04%;"></div>
<div class="timebox" style="margin-left:91.52%;width:1.04%;"></div>
<div class="timebox" style="margin-left:95.68%;width:1.04%;"></div>
</div>


<div id="timelinehours" style="background: #fff;width: 100%;height: 2px;margin: 0 auto;">
<div class="timeboxhour" >0</div>  
<div class="timeboxhour" >1</div>   
<div class="timeboxhour" >2</div> 
<div class="timeboxhour" >3</div> 
<div class="timeboxhour" >4</div>    
<div class="timeboxhour" >5</div>     
<div class="timeboxhour" >6</div>   
<div class="timeboxhour" >7</div> 
<div class="timeboxhour" >8</div>   
<div class="timeboxhour" >9</div>    
<div class="timeboxhour" >10</div>  
<div class="timeboxhour" >11</div>       
<div class="timeboxhour" >12</div>  
<div class="timeboxhour" >13</div>  
<div class="timeboxhour" >14</div>    
<div class="timeboxhour" >15</div> 
<div class="timeboxhour" >16</div>  
<div class="timeboxhour" >17</div> 
<div class="timeboxhour" >18</div>     
<div class="timeboxhour" >19</div> 
<div class="timeboxhour" >20</div>    
<div class="timeboxhour" >21</div>  
<div class="timeboxhour" >22</div>     
<div class="timeboxhour" >23</div>  
</div>

You can see it in action on JS Fiddle.

The timeline is width 100% and 4.16% represents an hour (100/24 = 4.16). The little blue bar are 1.04% width so it represents 15 minutes.

But as you can see, it doesn't work well because the blue bars are not always in the right places:

Can someone explain me the problem?

Upvotes: 1

Views: 83

Answers (2)

Michał Perłakowski
Michał Perłakowski

Reputation: 92521

It's a rounding problem. Since the width values are in percents, it calculates to a number like 8.81463px and browser then rounds it to 9px. For one element it shouldn't be a problem, but if it's 24 elements, the 8.81463px * 24 gives 211.55px, while 9px * 24 gives 216px As you see, it's almost 5px difference.

As already mentioned by @NiZa, it could be solved by adding position: relative; to the #timeline element, but I think a better solution would be to use Flexbox.

See example implementation of your timeline:

#timeline {
  display: flex;
  background: #fff;
  width: 100%;
  height: 2px;
  margin: 0 auto;
}
.timebox {
  height: 2px;
  background: #7D80E6;
  width: 1.04%;
  margin-right: auto;
}
#timelinehours {
  display: flex;
  background: #fff;
  width: 100%;
  height: 2px;
  margin: 0 auto;
}
.timeboxhour {
  height: 2px;
  background: #eee;
  color: #666;
  font-size: 0.8em;
  text-align: left;
  flex: 1;
}
<div id="timeline">
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
<div class="timebox"></div>
</div>


<div id="timelinehours">
<div class="timeboxhour" >0</div>  
<div class="timeboxhour" >1</div>   
<div class="timeboxhour" >2</div> 
<div class="timeboxhour" >3</div> 
<div class="timeboxhour" >4</div>    
<div class="timeboxhour" >5</div>     
<div class="timeboxhour" >6</div>   
<div class="timeboxhour" >7</div> 
<div class="timeboxhour" >8</div>   
<div class="timeboxhour" >9</div>    
<div class="timeboxhour" >10</div>  
<div class="timeboxhour" >11</div>       
<div class="timeboxhour" >12</div>  
<div class="timeboxhour" >13</div>  
<div class="timeboxhour" >14</div>    
<div class="timeboxhour" >15</div> 
<div class="timeboxhour" >16</div>  
<div class="timeboxhour" >17</div> 
<div class="timeboxhour" >18</div>     
<div class="timeboxhour" >19</div> 
<div class="timeboxhour" >20</div>    
<div class="timeboxhour" >21</div>  
<div class="timeboxhour" >22</div>     
<div class="timeboxhour" >23</div>  
</div>

You can learn more about Flexbox from A Complete Guide to Flexbox on CSS-Tricks or from MDN docs.

Upvotes: 1

NiZa
NiZa

Reputation: 3926

Add position:relative; to your #timeline.

Upvotes: 3

Related Questions