I’m trying to create a Single Page Application with a simple layout of Header -> Content -> Footer using Vue3 and the Bootstrap 5 framework.
I am trying to get the Content to fill the space between header and footer and footer to flush to the bottom of page & content so there is no overlap. However the application just renders everything on the top half of the page leaving the bottom half a white space. I’ve tried a flexbox approach however something doesn’t seem to be clicking right.
App.vue
JavaScript
x
45
45
1
<template>
2
<div id="app">
3
<div>
4
<HeaderBar></HeaderBar>
5
<div class="content"><router-view></router-view></div>
6
<FooterBar></FooterBar>
7
</div>
8
</div>
9
</template>
10
11
<script>
12
import HeaderBar from "@/components/HeaderBar.vue";
13
import FooterBar from "@/components/FooterBar.vue";
14
15
export default {
16
components: {
17
HeaderBar,
18
FooterBar,
19
},
20
};
21
</script>
22
23
<style>
24
body {
25
display: flex;
26
flex-direction: column;
27
height: 100vh;
28
}
29
30
#app {
31
font-family: Avenir, Helvetica, Arial, sans-serif;
32
-webkit-font-smoothing: antialiased;
33
-moz-osx-font-smoothing: grayscale;
34
}
35
36
.content {
37
background-image: url("../src/assets/background.png");
38
background-repeat: no-repeat;
39
background-attachment: scroll;
40
background-position: center center;
41
background-size: cover;
42
flex-shrink: 0;
43
}
44
</style>
45
HeaderBar.vue
JavaScript
1
90
90
1
<template>
2
<div>
3
<header class="bg-dark bg-gradient d-flex justify-content-center">
4
<ul class="nav nav-pill p-2">
5
<li class="nav-item">
6
<a class="nav-link fw-bold heading"> Title </a>
7
</li>
8
</ul>
9
</header>
10
<nav
11
class="navbar navbar-expand-lg navbar-dark bg-dark"
12
aria-label="Tenth navbar example"
13
>
14
<div class="container-fluid">
15
<button
16
class="navbar-toggler"
17
type="button"
18
data-bs-toggle="collapse"
19
data-bs-target="#navbarsExample08"
20
aria-controls="navbarsExample08"
21
aria-expanded="false"
22
aria-label="Toggle navigation"
23
>
24
<span class="navbar-toggler-icon"></span>
25
</button>
26
27
<div
28
class="collapse navbar-collapse justify-content-md-center"
29
id="navbarsExample08"
30
>
31
<ul class="navbar-nav justify-content-around">
32
<li class="nav-item pr-2">
33
<router-link class="nav-link lead" style="font-size: 2em" to="/"
34
>HOME</router-link
35
>
36
</li>
37
<li class="nav-item pr-2">
38
<router-link
39
class="nav-link lead"
40
style="font-size: 2em"
41
to="/about"
42
>ABOUT</router-link
43
>
44
</li>
45
<li class="nav-item pr-2">
46
<router-link
47
class="nav-link lead"
48
style="font-size: 2em"
49
to="/gallery"
50
>GALLERY</router-link
51
>
52
</li>
53
<li class="nav-item pr-2">
54
<router-link
55
class="nav-link lead"
56
style="font-size: 2em"
57
to="/cms"
58
>CMS</router-link
59
>
60
</li>
61
</ul>
62
</div>
63
</div>
64
</nav>
65
</div>
66
</template>
67
68
<style scoped>
69
@font-face {
70
font-family: "Mythical Snow";
71
src: URL("../assets/fonts/MysticalSnow.ttf") format("truetype");
72
}
73
74
.heading {
75
font-family: "Mythical Snow";
76
font-size: 4em;
77
color: #6a7363;
78
}
79
80
nav a {
81
font-weight: bold !important;
82
color: #2c3e50;
83
}
84
85
nav a.router-link-exact-active {
86
color: #ffffe0 !important;
87
}
88
</style>
89
90
FooterBar.vue
JavaScript
1
53
53
1
<template>
2
<div id="footer">
3
<footer class="bg-dark text-center text-white mt-auto">
4
<!-- Grid container -->
5
<div class="container p-4 pb-0">
6
<!-- Section: Social media -->
7
<section class="mb-4">
8
<!-- Home -->
9
<router-link
10
to="/"
11
class="btn btn-outline-light btn-floating m-1"
12
role="button"
13
><i class="bi bi-house-fill fa-2x"></i
14
></router-link>
15
16
<!-- About -->
17
<router-link
18
to="/about"
19
class="btn btn-outline-light btn-floating m-1"
20
role="button"
21
><i class="bi bi-file-person fa-2x"></i
22
></router-link>
23
</section>
24
<!-- Section: Social media -->
25
</div>
26
<!-- Grid container -->
27
28
<!-- Copyright -->
29
<div class="text-center p-3" style="background-color: rgba(0, 0, 0, 0.2)">
30
© 2022 Copyright:
31
<a class="text-white"></a>
32
</div>
33
<!-- Copyright -->
34
</footer>
35
</div>
36
</template>
37
38
<style scoped>
39
.icon {
40
color: #ffffff;
41
}
42
43
.icon:hover {
44
color: #000000;
45
}
46
47
footer {
48
position: sticky;
49
width: 100%;
50
}
51
</style>
52
53
Advertisement
Answer
JavaScript
1
14
14
1
<style>
2
#app {
3
display: flex;
4
flex-direction: column;
5
justify-content: space-between;
6
height: 98vh;
7
font-family: Avenir, Helvetica, Arial, sans-serif;
8
-webkit-font-smoothing: antialiased;
9
-moz-osx-font-smoothing: grayscale;
10
}
11
.content {
12
/* */
13
}
14
</style>
JavaScript
1
5
1
<template>
2
<HeaderBar></HeaderBar>
3
<div class="content"><router-view></router-view></div>
4
<FooterBar></FooterBar>
5
</template>
Strip the two div
‘s around HeaderBar
and FooterBar
in App.vue
.
Remove all styles from body
and put them into #app
, add justify-content: space-between
.
With height: 100vh
you’ll get a scrollbar. Use 98 to avoid that.