I was able to fix this by using
table-layout: fixed;
to evenly distribute the table cells rather than calculating it on page load. Not sure why I didn't think of this before.
سؤال
I'm working on making a navigation bar at the bottom of the webpage (for mobile layouts), and I use jQuery to resize the navigation after the page has loaded.
I have each button as a cell in a table , and each cell contains an image. I'm trying to set the image dimensions based on the size of the element. What I have now works exactly like I want it, but I don't know why.
The source of my confusion:
$("img.nav").each(function() {
$(this).width(); // commenting out this line changes the width of each <td> element
$(this).css("display", "block");
$(this).css("height", "80%");
$(this).css("width", "auto");
});
Here's what I get when I print the td's width:
With $(this).width(); as is:
w 0: 217
w 1: 217
w 2: 217
Which is perfect. Here's the output when I comment out that line:
w 0: 210
w 1: 200
w 2: 241
Not perfect. I need them all to be the same.
E: Also, removing the "display: none;" line in the CSS file simulates the same problem.
Here's the rest of my code (it's short):
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/globals.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="cordova.js"></script>
<script src="js/libjs.js"></script>
<title></title>
</head>
<body>
<div id="content"><p>Some example text that does nothing.</p></div>
<nav>
<table>
<tr>
<td id="nav_home" class="active">
<img class="center nav" src="img/home.png" alt="img_nav_home" width="150" height="200"/>
</td>
<td id="nav_map">
<img class="center nav" src="img/map.png" alt="img_nav_map" width="103" height="200"/>
</td>
<td id="nav_send">
<img class="center nav" src="img/send.png" alt="img_nav_send" width="286" height="200"/>
</td>
</tr>
</table>
</nav>
</body>
</html>
CSS:
*
{
padding: 0px;
margin: 0px;
width: 100%;
height: 100%;
border-style: none;
font-family: "Berlin Sans FB", Arial, sans-serif;
color: #383c47;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); /* transparent link selection, last value opacity 0 to 1.0 */
-webkit-touch-callout: none; /* prevent callout to copy image */
-webkit-text-size-adjust: none; /* prevent resizing text to fit */
-webkit-user-select: none; /* prevent copy paste */
}
/* Centers an image both horizontally and vertically in it's container. */
img.center {
display: block;
margin: auto;
}
body {
background-image: url(../img/bg.png);
}
#content {
background-color: white;
width: 70%;
height: 70%;
}
#content p {
padding: 5%;
}
/* The navigation bar at the bottom of each page. */
nav {
background-color: #b50043;
width: 100%;
height: 18%;
}
nav table {
border-spacing: 0px;
}
nav table .active {
background-color: #383c47;
}
nav table img.nav {
display: none; /* Also, removing this line will cause the same problem */
}
nav table #nav_home {
background-color: lightblue;
}
nav table #nav_map {
background-color: green;
}
nav table #nav_send {
background-color: blue;
}
jQuery:
// Centers the element both vertically and horizontally in the given element.
// Allows Top and Left offsets to account for "fixed" elements in the parent.
// Does not work with images (images work a little differently).
jQuery.fn.center = function(parent, offsetTop, offsetLeft) {
$(this).css("position", "absolute");
$(this).css("top", ($(parent).height() - this.outerHeight()) / 2 + offsetTop);
$(this).css("left", ($(parent).width() - this.outerWidth()) / 2 + offsetLeft);
return $(this);
}
// Use .resize and .ready to adjust layout based on screen size
$(window).resize(function() {
$("#content").center($(window), -($("nav").height() / 2), 0);
// positions the navigation bar at the bottom of the page
$("nav").css("position", "fixed");
$("nav").css("top", $(window).height() - $("nav").height());
// equally distribute nav buttons over the width of the screen
$("nav table tr > td").each(function() {
$(this).width($("nav").width() / $(this).length);
$(this).height($("nav").height());
});
$("img.nav").each(function() {
//$(this).width();
$(this).css("display", "block");
$(this).css("height", "80%");
$(this).css("width", "auto");
});
$("td").each(function(i) {
console.log("w " + i + ": " + $(this).width());
})
});
$(document).ready(function() {
$(window).trigger('resize');
});
Thanks in advance!
المحلول 2
I was able to fix this by using
table-layout: fixed;
to evenly distribute the table cells rather than calculating it on page load. Not sure why I didn't think of this before.
نصائح أخرى
You should change your call resize on on $(window).load
instead of $(document).ready
.
The problem is in next thing - document.ready
event is fired when when HTML-Document is loaded and DOM is ready but you need to wait until all images are loaded as well.
Documentation: