preface
Recently, I want to implement a customized responsive top navigation bar, that is, support normal access of mainstream devices (Phone, Pad, PC), and achieve the corresponding display effect according to the screen proportion.
The following methods have been tried
- Navigation bar provided by Element UI (monotonous style, no responsive effect)
- Navigation bar provided by BootStrap (responsive effects, additional dependency packages need to be introduced, and customization effects are cumbersome)
From this, I came up with the idea of implementing a responsive top navigation bar myself, which should have the following features:
- Simple implementation without introducing additional dependency libraries (or fewer)
- Can realize dynamic add function menu, personalized customization is relatively simple
- To achieve the compatibility of a variety of devices, to ensure that the display effect is more beautiful
Results show
- Tips: If the GIF image is not loaded, please try refreshing.
Prepare in advance
- Master H5 and CSS layout skills
- Understand CSS media query
- Master an incremental framework (implemented here with Vue)
- To achieve the navigation bar has a certain design planning
implementation
Ideas:
The navigation bar is divided into left and right parts. When the width of the window is reduced, CSS media query is used to modify the style. When the width is reduced to the minimum, hide the current navigation display and replace it with a drop-down list display.
- Style changes are implemented primarily through CSS media queries
- To facilitate expansion, the navigation option is set to an array of objects
Header.vue
- Template section
<template> <! --xs: phone, sm: pad, md: pc, lg: 2k-pc, xl: 4k-pc--> <nav class="header"> <! -- Top navigation --> <div class="container">
<ul class="container-left-ul">
<li>
<img id="icon" src="@assets/image/icon.png"/>
</li>
<li :class="$store.state.activeName === item.activeName ? 'menu-item-active' : 'container-left-li'" @click="toActiveMenuItem(item)"
v-for="(item, index) in leftMenuList" :key="index">
{{ item.titleName }}
</li>
</ul>
<ul class="container-right-ul">
<li :class="$store.state.activeName === item.activeName ? 'menu-item-active' : 'container-right-li'" @click="toActiveMenuItem(item)"
v-for="(item, index) in rightMenuList" :key="index">
{{ item.titleName }}
</li>
<li id="bars" @click="dropDownShow = ! dropDownShow">
<i class="fa fa-bars fa-lg"/> </li> </ul> </div> <! Dropdown menu --> < Transition name="dropdown-fade-show">
<div v-show="dropDownShow" class="dropdown">
<ul class="dropdown-top-ul">
<li class="dropdown-top-li" v-for="(item, index) in leftMenuList" :key="index" @click="toActiveMenuItem(item)">{{ item.titleName }}</li>
</ul>
<ul class="dropdown-bottom-ul">
<li class="dropdown-bottom-li" v-for="(item, index) in rightMenuList" :key="index" @click="toActiveMenuItem(item)">{{ item.titleName }}</li>
</ul>
</div>
</transition>
</nav>
</template>
Copy the code
- Script part
export default {
name: 'Header'.data () {
return {
dropDownShow: false// Control the drop-down menu to display leftMenuList: [// left menu contents {activeName:'Home', titleName: 'home', activeUrl: '/index' },
{ activeName: 'Infinity', titleName: 'Infinity', activeUrl: '/infinity' },
{ activeName: 'About', titleName: 'about', activeUrl: '/about'}], rightMenuList: [// right menu contents {activeName:'Support', titleName: 'sponsor', activeUrl: '/support' }
],
activeName: ' '}}, methods: {toActiveMenuItem (item) {this.activename = item.titlename this.$router.push(item.activeUrl)
this.dropDownShow = false}}}Copy the code
- CSS section (use stylus here)
<style lang="stylus" scoped>
@import ".. /.. /assets/stylus/init.stylus" // Initialize the navigation parameters
@import ".. /.. /assets/stylus/fade.stylus" // Implement navigation drop-down to display animation effects
.header
color $headerTextColor
background $headerBg
height $header-height
width 100%
position fixed
top 0
padding 0 10%
.container
width 100%
height 100%
.container-left-ul
float left
li
height 100%
line-height $header-height
width $header-li-width
display inline-block
#icon
height 30px
vertical-align middle
transition transform 0.5 s
#icon:hover
transform scale(1.5.1.5) rotate(180deg)
.container-left-li:hover
color $menu-active-color
box-shadow 0px -4px 0px $menu-active-color inset
.container-right-ul
float right
li
height 100%
line-height $header-height
width $header-li-width
display inline-block
.container-right-li:hover
color $menu-active-color
box-shadow:0px -4px 0px $menu-active-color inset
#bars > i
padding 8px 14px
border 1px $headerTextColor solid
border-radius 5px
.dropdown
border 1px red solid
width 100%
background $headerBg
li
height 40px
line-height 40px
li:hover
background black
.menu-item-active
color $menu-active-color
box-shadow 0px -4px 0px $menu-active-color inset
@media screen and (max-width: 992px) {
.header {
padding 0
}
}
@media screen and (max-width: 768px) {
.container-left-li {
displaynone ! important }.container-right-li {
displaynone ! important } } @media screen and (min-width: 768px) {
#bars {
display none
}
.dropdown {
display none
}
}
</style>
Copy the code
- init.stylus
- Params.stylus (Parameter configuration)
- Stylus (color configuration)
/* params.stylus (parameter configuration) */
// Set the parameters for the header
$header-height = 60px
$header-li-width = 70px
// The navigation bar menu activates colors
$menu-active-color = $googleYellow
$headerBg = #282C34
$headerTextColor = #ffffff
Stylus (color configuration) */
$googleRed = #f4433c
$googleBlue = #2d85f0
$googleGreen = #0aa858
$googleYellow = #ffbc32
Copy the code
Tips:
- The introduction of CSS variables can better solve the topic related configuration issues
After the navigation bar is implemented and the screen size is reduced, the drop-down menu is displayed. At this time, animation should be added to the display and disappearance of the menu to achieve a similar effect to el-Zoom-in-top (with the help of the
of Vue).
- fade.stylus
Dropdown-fade-show-enter -active animation fadeshow.25s. Dropdown-fade-show-leave-to animation fadeShow .25s reverse @keyframes fadeShow { 0% { transform-origin 0 top transform scaleY(0) opacity 0 } 100% { transform-origin 0 top transform scaleY(1) opacity 1 } }Copy the code
conclusion
This is just a design idea for a responsive navigation layout, but the details can still be optimized.
Points to be optimized:
- You can optimize styles through design and CSS
- Combine Vuex and browser local cache to solve the problem of recovering navigation bar status after page refresh
Optimize the code follow-up update, also welcome you to actively discuss, common progress!
My Jane book ———— play soy sauce