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