I'm creating an accordion-like mobile webpage, trying to use the flex
family of CSS properties.
In short, I'm getting this:
but I want this:
The page consists solely of a set of <section>
s, each of them having a clickable <header>
and an <article>
:
<body>
<section id="about">
<header><a href="#about">About</a></header>
<article>
This will be about.
</article>
</section>
<section id="map">
<header><a href="#map">Map</a></header>
<article>
This will be a map.
</article>
</section>
<section id="talk">
<header><a href="#talk">Talk</a></header>
<article>
This will be talk
</article>
</section>
</body>
Only one <article>
should be displayed at any given time (the rest of them hidden), so:
<style>
...
section:not(:target) article {
display: none;
}
</style>
So far, so good.
In order to use the full height of the device screen, that is, the height of the expanded section should be deviceheight - height of all the header elements
. I've experimented with the flex
properties, and I have no problem making it work as desired on my PC screen (using Chrome):
html {
height: 100%
}
body {
height: 100%;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
align-items: stretch;
align-content: stretch;
justify-content: flex-start;
background: yellow;
}
section:target {
flex: 1 1 auto;
}
section:not(:target) article {
display: none;
}
section:not(:target) {
height: auto;
flex: 0 1 auto;
}
section {
border: 1px solid black;
background-color: green;
display: flex;
flex-direction: column;
align-items: stretch;
align-content: stretch;
}
header {
padding: 0.2em;
background-image: linear-gradient(to bottom, black, rgba(100, 100, 100, 128));
color: white;
font-size: 12pt;
font-weight: bold;
font-family: "American Typewriter", serif;
cursor: pointer;
flex: 0 0 auto;
}
header a {
color: white;
}
article {
width: 100%;
height: 100%;
display: block;
background-color: yellowgreen;
flex: 1 0 auto;
}
This produces something like this, on a desktop PC with Chrome, when the Map section is expanded:
The Map section takes all available space, just like I intended.
Now, with Mobile Safari, the expanded section does not use all available vertical space, but instead only enough to display its contents:
As can be seen, the green Map section does not push the Talk header down to the bottom of the screen, instead the yellow body
background color comes through.
I thought this would be rectified by specifying height=device-height
, but that does not change anything:
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width, height=device-height"/>
I'd like the expanded section to use all available space, so that no yellow background color is visible. What am I missing in my CSS rules? I'd like to avoid resorting to JavaScript.
The full code can be fetched from https://gist.github.com/vramdal/4d764aef41bd39e8c96d
It seems Safari lags a little behind Chrome in supporting flex
.
This was simply a matter of using -webkit
prefixes. With those in place, and removing height=device-height
, I got exactly what I wanted.
Here's the complete code:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width"/>
<meta charset="utf-8"/>
<style type="text/css">
html {
height: 100%
}
body {
height: 100%;
margin: 0;
padding: 0;
display: flex;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
align-items: stretch;
-webkit-align-items: stretch;
align-content: stretch;
-webkit-align-content: stretch;
justify-content: flex-start;
-webkit-justify-content: flex-start;
background: yellow;
}
section:target {
flex: 1 1 auto;
-webkit-flex: 1 1 auto;
}
section:not(:target) article {
display: none;
}
section:not(:target) {
height: auto;
flex: 0 1 auto;
-webkit-flex: 0 1 auto;
}
section {
transition: flex 500ms ease-out;
border: 1px solid black;
background-color: green;
display: flex;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
align-items: stretch;
-webkit-align-items: stretch;
align-content: stretch;
-webkit-align-content: stretch;
}
header {
padding: 0.2em;
background-image: linear-gradient(to bottom, black, rgba(100, 100, 100, 128));
color: white;
font-size: 12pt;
font-weight: bold;
font-family: "American Typewriter", serif;
cursor: pointer;
flex: 0 0 auto;
-webkit-flex: 0 0 auto;
}
article {
width: 100%;
display: block;
background-color: yellowgreen;
flex: 1 0 auto;
-webkit-flex: 1 0 auto;
}
</style>
</head>
<body>
<section id="About">
<header><a href="#About">About</a></header>
<article>
This will be about.
</article>
</section>
<section id="map">
<header><a href="#map">Map</a></header>
<article>
This will be a map.
</article>
</section>
<section id="talk">
<header><a href="#talk">Talk</a></header>
<article>
This will be talk
</article>
</section>
</body>
</html>