Semantic UI导航菜单的响应式替代方案

15

Semantic UI 在菜单集合方面存在一些问题。简而言之,它根本不具备响应式设计,最接近的解决方法是使用"stackable"实现将菜单堆叠显示。

有没有人可以推荐一个能够很好地与 Semantic UI 集成的导航菜单?

感谢任何意见。


你能分享一下你想要的响应式菜单是什么样子吗? - Albert Israel
为什么Stackable不是一个好的解决方案? - Weedoze
1
@Weedoze 因为可堆叠的主导航菜单在移动屏幕上始终是“打开”的,覆盖了大部分第一页。Semantic 的首席开发人员表示没有计划制作真正响应式的菜单,因此我正在寻找其他解决方案。 - pbarney
@Albert Israel,我正在寻找一个顶部水平多级导航栏,在移动设备上可以压缩成标准的“汉堡包”菜单。 - pbarney
我相信在 Semantic UI 中有一种方法可以实现这一点。你可以在桌面上使用标准菜单,在较小的设备上使用侧边栏。 - Albert Israel
3个回答

9
我已经修改了之前的代码,并尝试使语义化UI导航具有响应性。这个HTML代码基于语义化UI,我尽可能地保持它的精简,并添加了CSS和JS代码以实现过渡特效。希望这可以帮到您。
我已经用新代码创建了一个fiddle。下面是链接: https://jsfiddle.net/1712/g6agpoy9/
<!-- language: lang-css -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/reset.min.css" rel="stylesheet" />

    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/site.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/container.min.css" rel="stylesheet" />

    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/grid.min.css" rel="stylesheet" />

    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/header.min.css" rel="stylesheet" />

    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/menu.min.css" rel="stylesheet" />

    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/dropdown.css" rel="stylesheet" />

    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/transition.min.css" rel="stylesheet" />



    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/sidebar.min.css" rel="stylesheet" />

    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/icon.min.css" rel="stylesheet" />

    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/segment.min.css" rel="stylesheet" />


    .hidden.menu {
      display: none;
    }
    .masthead.segment {
      min-height: 700px;
      padding: 1em 0em;
    }
    .masthead .logo.item img {
      margin-right: 1em;
    }
    .masthead .ui.menu .ui.button {
      margin-left: 0.5em;
    }
    .masthead h1.ui.header {
      margin-top: 3em;
      margin-bottom: 0em;
      font-size: 4em;
      font-weight: normal;
    }
    .masthead h2 {
      font-size: 1.7em;
      font-weight: normal;
    }
    .ui.vertical.stripe {
      padding: 8em 0em;
    }
    .ui.vertical.stripe h3 {
      font-size: 2em;
    }
    .ui.vertical.stripe .button + h3,
    .ui.vertical.stripe p + h3 {
      margin-top: 3em;
    }
    .ui.vertical.stripe .floated.image {
      clear: both;
    }
    .ui.vertical.stripe p {
      font-size: 1.33em;
    }
    .ui.vertical.stripe .horizontal.divider {
      margin: 3em 0em;
    }
    .quote.stripe.segment {
      padding: 0em;
    }
    .quote.stripe.segment .grid .column {
      padding-top: 5em;
      padding-bottom: 5em;
    }
    .footer.segment {
      padding: 5em 0em;
    }
    .secondary.pointing.menu .toc.item {
      display: none;
    }
    @media only screen and (max-width: 700px) {
      .ui.fixed.menu {
        display: none !important;
      }
      .secondary.pointing.menu .item,
      .secondary.pointing.menu .menu {
        display: none;
      }
      .secondary.pointing.menu .toc.item {
        display: block;
      }
      .masthead.segment {
        min-height: 350px;
      }
      .masthead h1.ui.header {
        font-size: 2em;
        margin-top: 1.5em;
      }
      .masthead h2 {
        margin-top: 0.5em;
        font-size: 1.5em;
      }
    }

<!-- language: lang-html -->



    <!-- Following Menu -->
    <div class="pusher">
      <div class="ui inverted vertical masthead center aligned segment">
        <div class="ui container">
          <div class="ui large secondary inverted pointing menu">
            <a class="toc item">
              <i class="sidebar icon"></i>
            </a>
            <a class="active item">Home</a>
            <a class="item">Work</a>
            <a class="item">Company</a>
            <a class="item">Careers</a>
          </div>
        </div>
      </div>
    </div>
    <!-- Sidebar Menu -->
    <div class="ui vertical inverted sidebar menu">
      <a class="active item">Home</a>
      <a class="item">Work</a>
      <a class="item">Company</a>
      <a class="item">Careers</a>
      <a class="item">Login</a>
      <a class="item">Signup</a>
    </div>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/semantic.min.js"></script>

    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/sidebar.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/visibility.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.6/components/transition.js"></script>
<!-- language: lang-js -->

    $(document)
      .ready(function() {

        // create sidebar and attach to menu open
        $('.ui.sidebar')
          .sidebar('attach events', '.toc.item');

      });
<!-- end snippet -->

4
使用最小的HTML和CSS代码,我们可以实现一个响应式菜单导航,该导航可以自定义而且无需JavaScript。使用off-canvas属性,我们可以隐藏基本菜单,在移动视图中,菜单链接出现在左侧,屏幕分为菜单80%和内容20%。对于移动设备,我使用标签来表示汉堡菜单,对于桌面端则将标签隐藏。关于浏览器兼容性,Off Canvas菜单的使用场景通常是智能手机和平板电脑,这些设备都配备了现代浏览器。所有IE8及更高版本的浏览器都支持此功能。
以下是导航样例代码:

@import "compass/css3";
@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,600,700);

* {
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  height: 100%;
}
body {
  margin: .55em;
  color: black;
}

/* custom scrollbar */
::-webkit-scrollbar {
  width: .95em;
}

::-webkit-scrollbar-track {
  background-color: rgba(217, 217, 217, 0.5);
}

::-webkit-scrollbar-thumb {
  background: rgba(184, 184, 184, 0.5);
  box-shadow: inset 0.05em 0.05em 0 rgba(0, 0, 0, 0.1), inset 0 -0.05em 0 rgba(0, 0, 0, 0.07);
}

/* Advanced Checkbox Hack */
body {
  -webkit-animation: bugfix infinite 1s;
}

@-webkit-keyframes bugfix {
  from {
    padding: 0;
  }
  to {
    padding: 0;
  }
}

input[type=checkbox] {
  position: absolute;
  top: -9999px;
  left: -9999px;
}

label {
  position: absolute;
  left: 0;
  display: none;
  width: 2em;
  height: 2.25em;
  padding: .35em;
  font-size: 1.1em;
  color: #fff;
  transition: color .3s ease-in-out;
  cursor: pointer;
  user-select: none;
  margin: 0;
  background: rgba(0, 0, 0, 0.4);
}

/* big screens */
nav[role="off-canvas"] {
  position: relative;
  width: 50em;
  margin: 0 auto;
  transition-duration: .3s, .5s;
  transition-timing-function: ease-in-out;
  transition-property: left, opacity, box-shadow;
}

nav[role="off-canvas"] a {
  color: #fff;
  text-decoration: none;
  font: 1.4em 'Open Sans', sans-serif;
  transition: color .3s ease-in-out;
  display: table-cell;
  vertical-align: middle;
}

nav[role="off-canvas"] ul {
  padding: 0;
  margin: 0 auto;
  width: 100%;
}

nav[role="off-canvas"] ul > li {
  float: left;
  padding: .5em 0;
  width: 8em;
  margin: .5em 0;
  opacity: .8;
  text-transform: uppercase;
  display: table;
  background: rgba(247, 52, 8, 0.65);
  cursor: pointer;
  text-align: center;
  transition-duration: .3s;
  transition-timing-function: ease-in-out;
  transition-property: box-shadow, color, opacity, padding-left;
  cursor: pointer;
}

nav[role="off-canvas"] ul > li:hover {
  color: #fff;
  opacity: 1;
  box-shadow: 0.5em 0 0 0 rgba(255, 255, 255, 0.95);
}

nav[role="off-canvas"] ul > li:hover > a {
  color: #fff;
}

nav[role="off-canvas"] ul > li:nth-child(2) {
  background: rgba(247, 183, 8, 0.65);
}

nav[role="off-canvas"] ul > li:nth-child(3) {
  background: rgba(32, 247, 8, 0.65);
}

nav[role="off-canvas"] ul > li:nth-child(4) {
  background: rgba(8, 231, 247, 0.65);
}

nav[role="off-canvas"] ul > li:nth-child(5) {
  background: rgba(8, 72, 247, 0.65);
}

/* small screens */
@media screen and (max-width: 44em) {
  html,
  body {
    margin: 0;
    overflow-x: hidden;
  }

  .content {
    margin: 2.5em .5em 0 .5em;
  }

  nav[role="off-canvas"] {
    position: absolute;
    top: 3em;
    left: -20em;
    width: 20em;
    opacity: 0;
  }

  nav[role="off-canvas"] ul > li {
    height: 100%;
    width: 100%;
    text-align: left;
    margin: 0;
  }

  nav[role="off-canvas"] ul > li:hover {
    box-shadow: inset 0 0 0 0.15em rgba(255, 255, 255, 0.45);
  }

  label {
    display: block;
  }

  label:after {
    position: absolute;
    right: .25em;
    top: 0;
    content: "\2261";
    font-size: 1.8em;
  }

  label:hover,
  input:checked ~ label {
    color: #000;
  }

  input:checked ~ nav[role="off-canvas"] {
    opacity: 1;
    left: 0;
    box-shadow: -30em 0 0 30em rgba(0, 0, 0, 0.3);
  }

  input:checked ~ nav[role="off-canvas"] ul > li {
    padding: .55em .55em .55em 1.5em;
  }

  input:checked ~ nav[role="off-canvas"] ul > li:hover {
    padding-left: 3.5em;
  }

  input:checked ~ nav[role="off-canvas"] ul > li:after {
    position: absolute;
    right: .25em;
    content: "\203A";
    font: bold 1.4em sans-serif;
    color: inherit;
  }

  input:checked ~ .content {
    margin-left: 20.5em;
    margin-right: -20.5em;
  }
}
<input type="checkbox" id="menu">
<label for="menu" onclick></label>
<nav role="off-canvas">
    <ul>
        <li><a href="#">Stream</a></li>
        <li><a href="#">Lab</a></li>
        <li><a href="#">Projects</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
    </ul>
</nav>
</div>


谢谢!看起来是一个可行的例子。我会尝试在我的网站上实现它,然后奖励你! - Alexander Tyapkov
我刚刚意识到你的解决方案并不完全符合要求。如果我要使用它,就需要删除语义化菜单。而我需要一个在移动电话上可以折叠为堆叠式菜单的语义化菜单。 - Alexander Tyapkov
1
请查看我最新的回答,我已经使用语义化UI HTML更新了代码。 - Priyanka Thombre
非常感谢!我有一个相关的问题。请通过聊天或电子邮件与我联系。 - Alexander Tyapkov

3

我在下面编写了一个示例代码,演示如何使用Semantic UI实现响应式“汉堡包”菜单。点击JSFiddle中的Full page链接以查看完整宽度的菜单,然后调整浏览器大小以查看响应性。

$('.ui.sidebar').sidebar({
    context: $('.pushable.segment'),
    transition: 'overlay'
}).sidebar('attach events', 'a#hamburger-link');
.my-content .ui.segment{
  min-height:500px;
  height:100%;
}
.ui.grid{
  padding:0 !important;
}
.pushable.segment{
  margin:0 !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/1.11.8/semantic.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/1.11.8/semantic.min.js"></script>
<div class="ui grid">
  <div class="computer only row">
    <div class="column">
      <div class="ui inverted blue menu">
        <a class="item">Menu Item A</a>
        <a class="item">Menu Item B</a>
        <a class="item">Menu Item C</a>
        <a class="item">Menu Item D</a>
      </div><!-- blue menu-->
    </div><!--column-->
  </div><!--computer only row-->
   <div class="tablet mobile only row">
    <div class="column">
      <div class="ui inverted blue menu">
        <a id="hamburger-link" class="item"><i class="bars icon"></i></a>
      </div>
    </div><!--column-->
  </div><!--computer only row-->
</div><!-- grid-->
<div class="ui pushable segment">
    <div class="ui sidebar inverted blue vertical menu">
      <a class="item">Menu Item A</a>
      <a class="item">Menu Item B</a>
      <a class="item">Menu Item C</a>
      <a class="item">Menu Item D</a>
    </div><!-- blue menu-->
    <div class="my-content pusher">
        <div class="ui segment">
        YOUR CONTENT HERE... ISN'T IT NICE? <i class="pointing up icon"></i>
        </div>
     </div>
</div>


1
我明白你的意思,但这并不是很DRY。需要两次复制菜单结构让我相信SUI的导航菜单系统存在某些缺陷。 - pbarney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接