I am building a phonegap application. I have the following:
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Three <br>a Half</li>
</ul>
How can I make the <li>
elements stretch vertically and fill the whole height of the page given that this needs to be dynamic so that it adapts to other viewports. The text inside the <li>
elements needs to be vertically centred and supports multiple lines.
Is there any clean way of doing this?
I suggest using the display: table
family of CSS3 rules. They'll be dynamic and maintain full height spacing if done correctly:
body, html {
height: 100%;
margin: 0;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
display: table;
width: 100%;
height: 100%;
}
ul li {
display: table-row;
}
ul li a { /* assuming an anchor child. Can be anything */
display: table-cell;
vertical-align: middle;
padding: 1em 3em;
}
Demo: http://jsfiddle.net/6z3q35x0/1/
There are two parts to your question: the first is to force the <ul>
element to stretch to fill the viewport, and the second is to vertically and horizontally center the <li>
content. However, the centering requires modifications to your markup. We can wrap all the content in <li>
using <div>
elements.
For centering, we can use CSS3 flexbox for that. This would be a JS-free solution, although it enjoys less cross-browser support. For viewport size, we can use the vw
and vh
units respectively.
ul {
display: flex;
flex-direction: column;
list-style: none;
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
}
li {
display: flex;
align-items: center;
justify-content: center;
flex-grow: 1;
}
li div {
}
/* For stylistics only */
li:nth-child(odd) {
background-color: #ddd;
}
<link href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.min.css" rel="stylesheet"/>
<ul>
<li><div>One</div></li>
<li><div>Two</div></li>
<li><div>Three</div></li>
<li><div>Three <br>a Half</div></li>
</ul>
However, there might be situations where using CSS flexbox and viewport units are not ideal — iOS7, for example, has a well-documented rendering bug that does not calculate vh
properly. In this case, we might have to rely on JS instead. The height of each <li>
is simply divided by the number of <li>
s present in the container.
var calcHeight = function() {
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var li = document.querySelectorAll("ul li");
for(var i=0; i<li.length; i++) {
li[i].style.height = (h/li.length)+'px';
}
}
calcHeight();
window.onresize = calcHeight();
ul {
list-style: none;
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
}
li {
display: block;
width: 100%;
position: relative;
}
li div {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
li:nth-child(odd) {
background-color: #ddd;
}
<link href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.min.css" rel="stylesheet"/>
<ul>
<li><div>One</div></li>
<li><div>Two</div></li>
<li><div>Three</div></li>
<li><div>Three <br>a Half</div></li>
</ul>
Here is a JavaScript solution, which will give the height
s according to the viewport's height
.
ul
to take the entire viewport's height:Demo on Fiddle
var li = document.getElementsByTagName('li');
function doMath() {
for (i = 0; i < li.length; i++) {
li[i].style.height = window.innerHeight / li.length + 'px';
}
}
doMath();
window.onresize = doMath;
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
background: rosybrown;
}
span {
display: block;
position: relative;
top: 50%;
text-align: center;
transform: translateY(-50%);
}
li:nth-of-type(2n) {
background: plum;
}
body {
margin: 0;
}
<ul>
<li><span>One</span></li>
<li><span>Two</span></li>
<li><span>Three</span></li>
<li><span>Three<br />a Half</span></li>
<li><span>Four</span></li>
<li><span>Five<br />a Half</span></li>
<li><span>Six</span></li>
</ul>
li
s to take the entire viewport's height:Demo on Fiddle
var li = document.getElementsByTagName('li');
function doMath() {
for (i = 0; i < li.length; i++) {
li[i].style.height = window.innerHeight + 'px';
}
}
doMath();
window.onresize = doMath;
ul {
padding: 0;
margin: 0;
list-style: none;
}
li {
background: rosybrown;
}
span {
display: block;
position: relative;
top: 50%;
text-align: center;
transform: translateY(-50%);
}
li:nth-of-type(2n) {
background: plum;
}
body {
margin: 0;
}
<ul>
<li><span>One</span></li>
<li><span>Two</span></li>
<li><span>Three</span></li>
<li><span>Three<br />a Half</span></li>
<li><span>Four</span></li>
<li><span>Five<br />a Half</span></li>
<li><span>Six</span></li>
</ul>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With