vux flexbox使用_使用Flexbox构建超级菜单

vux flexbox使用

Mega Menus with Flexbox

As you are probably aware, Flexbox has recently gained momentum with increasing browser support. It allows developers to build complex user interfaces without dealing with unwanted CSS and JavaScript hacks.

您可能已经知道,Flexbox最近通过增加对浏览器的支持而获得发展。 它允许开发人员构建复杂的用户界面,而无需处理不必要CSS和JavaScript hack。

Flexbox uses a linear layout model, which allows us to lay our content horizontally or vertically without involving calculations for spacing. The flex layout reacts responsively to the elements within the container, thus requiring fewer media queries.

Flexbox使用线性布局模型,该模型允许我们水平或垂直放置内容,而无需计算间距。 Flex布局对容器内的元素做出响应,因此需要较少的媒体查询。

In this article I will make use of this layout model to build a mega navigation menu and in the process you’ll see how simple it is to build and extend user interface components with flexbox.

在本文中,我将利用此布局模型构建大型导航菜单,在此过程中,您将看到使用flexbox构建和扩展用户界面组件非常简单。

I won’t discuss individual Flexbox properties in detail here, but instead the focus will be on the practical use of the features. For a basic introduction to Flexbox, please refer the following resources:

我不会在这里详细讨论各个Flexbox属性,而是将重点放在功能的实际使用上。 有关Flexbox的基本介绍,请参考以下资源:

我们正在建设什么? (What Are We Building?)

To get an idea of what I’ll be showing you how to build, take a look at the full-screen CodePen.

要了解我将向您展示如何构建的内容,请查看全屏CodePen

This tutorial is divided into three parts:

本教程分为三个部分:

  1. Building the navigation bar: Using flexbox to build a simple navigation bar for our imaginary e-commerce platform

    构建导航栏:使用flexbox为我们虚构的电子商务平台构建一个简单的导航栏
  2. Building a single drop-down section

    构建单个下拉部分
  3. Limiting a single drop-down section to three columns

    将单个下拉部分限制为三列

构建导航栏 (Building the Navigation Bar)

The markup for the navigation bar is simple. I will handle everything with two classes (navbar and menu) for the sake of this demo. The CSS here will exclude any styles unrelated to the tutorial.

导航栏的标记很简单。 为了这个演示,我将使用两个类( navbarmenu )来处理所有事情。 此处CSS将排除与本教程无关的任何样式。

<nav class="navbar">
  <ul class="menu">
    <li>
      <a href="#">
        Electronics
        <!-- FontAwesome icon -->
        <i class="fa fa-angle-down"></i>
      </a> 
    </li>

    <!-- ... More nav items here... -->

  <ul>
</nav>

The navbar class is responsible for centering our navigation bar in the available space, but I’m going to focus on the menu class where I will use flexbox.

navbar类负责将导航栏置于可用空间的中心,但是我将重点介绍将使用flexbox的menu类。

I want my navigation items to be laid out horizontally. Also, I want each item to be spaced equally and shrink as needed if there is not enough space.

我希望将导航项水平放置。 另外,如果空间不足,我希望每个项目的间距相等,并根据需要缩小。

First, I need to establish a flex formatting context on the .menu element, which I’ll do with display: flex. Now, all the direct children of the .menu element (which is the flex container) will be flex items.

首先,我需要在.menu元素上建立一个flex格式化上下文,我将使用display: flex来做。 现在, .menu元素的所有直接子元素(即flex容器)将都是flex项目。

Next, I want the menu items to be equal in width. I’ve added flex: 1 to make them grow uniformly with equal width. Here is the code:

接下来,我希望菜单项的宽度相等。 我添加了flex: 1使它们以相等的宽度均匀增长。 这是代码:

.navbar .menu {
  display: flex;
  position: relative;
}

.navbar .menu li {
  flex: 1;
  display: flex;
  text-align: center;
}

.navbar .menu a {
  flex: 1;
  justify-content: center;
  color: #ffffff;
  padding: 20px;
}

Looking at the code, you might be wondering why I repeated display: flex for all the flex items (.navbar .menu li).

查看代码,您可能想知道为什么我重复display: flex所有flex项目的flex( .navbar .menu li )。

In the demo, when you hover over a menu item, its background color changes. If I don’t set the display property of the flex items to flex, then only the li elements will have equal width and not the content inside them (i.e. some highlighted part will be clickable and others will not).

在演示中,将鼠标悬停在菜单项上时,其背景颜色会更改。 如果我没有将flex项目的display属性设置为flex ,那么只有li元素将具有相等的宽度,而内部元素的内容将不相等(即,某些突出显示的部分将是可单击的,而其他部分将无法单击)。

To make the content expand to the full width of its parent, I made the flex items themselves into flex containers. With this in place, I can then make each nested a element grow as wide as its parent (using flex: 1), thus making the full highlighted area clickable.

为了使内容扩展到其父对象的整个宽度,我将flex项本身放入了flex容器中。 与此到位,然后我可以使每个嵌套a元件生长为宽作为其父(使用flex: 1 ),从而使充满高亮区域点击。

Alternatively, I could have also achieved this without making li elements flex containers, but I’d have to use three additional properties (display: inline-block, width: 100%, box-sizing: border-box), which I would prefer to avoid.

另外,我也可以不用制作li elements flex容器就可以实现这一点,但是我不得不使用三个附加属性( display: inline-blockwidth: 100%box-sizing: border-box ),我更喜欢避免。

This demo shows what is done so far.

该演示演示了到目前为止已完成的工作

With a mere five CSS Flexbox properties, the navigation bar is ready. As you can see, this is a clean solution.

仅有五个CSS Flexbox属性,导航栏已准备就绪。 如您所见,这是一个干净的解决方案。

In the next section, I’ll show you how to build a single section of the mega navigation.

在下一部分中,我将向您展示如何构建大型导航的单个部分。

建立一个下拉菜单 (Building a Single Drop-down Section)

Below is the markup I’m going to use to build a single drop-down section, which will extend to multiple sections. The container__list item will be duplicated to create the other sections.

下面是我将用来构建单个下拉部分的标记,它将扩展到多个部分。 container__list项目将被复制以创建其他部分。

<ul class="container">
  <!-- single column -->
  <div class="container__list">
    <!-- menu item -->
    <div class="container__listItem">
      <div>Televisions</div>
    </div>

    <!-- ... other menu items here -->

  </div>
</ul>

The container is the flex container and each direct child (i.e. container__list) is a flex item. Each container__list has multiple navigation items, each wrapped by container__listItem. I’ve wrapped the content in a div, which I’ll come back to later.

container是flex容器,每个直接子代(即container__list )都是flex项。 每个container__list具有多个导航项,每个导航项都由container__listItem包装。 我将内容包装在div ,稍后再讲。

Here is the CSS:

这是CSS:

.container {
  /* initially hidden; display:flex on hover */
  display: none;
  position: absolute;
  top: 56px;
  left: 0;
  right: 0;
  background-color: #ffffff;
  padding: 20px;
  text-align: left;
}

.container__list {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
}

.container__listItem {
  flex: 0 0 25%;
  padding: 10px 30px;
}

.container__listItem > div {
  color: #DB6356;
}

Notice that I’ve used the flex-wrap property on container__list but I didn’t use this for the navigation bar itself. As mentioned earlier, I don’t want the navigation bar items to wrap to the next line when there is a shortage of space. Instead, they shrink equally when the available horizontal space is reduced.

请注意,我已经在container__list上使用了flex-wrap属性,但没有将其用于导航栏本身。 如前所述,当空间不足时,我不希望导航栏项换行到下一行。 相反,当可用的水平空间减小时,它们会平均缩小。

For the container__list items, however, the requirement is the other way around. I want my list item to use 25% of the space, thus accommodating a maximum of four items per row, which I can accomplish using flex-wrap: wrap.

但是,对于container__list项目,要求是相反的。 我希望列表项使用25%的空间,因此每行最多可容纳四个项,我可以使用flex-wrap: wrap来完成。

I’ve also set flex-grow to 0. This is useful because it prevents the items that are less than four from being equally spaced. By setting it to 0 I’m forcing the items to stick with 25% of the space.

我还将flex-grow设置为0 。 这很有用,因为它可以防止少于四个的项目均匀分布。 通过将其设置为0我迫使项目坚持使用25%的空间。

Now what about the content wrapped in div?. I wanted to cover a case where you may want to prevent content overflowing. This is pretty straightforward when your content is directly inside the flex child (i.e. container__listItem). I can use following code to replace clipped text with an ellipsis (“…”).

现在,用div包装的内容呢? 我想介绍一个您可能要防止内容溢出的情况。 当您的内容直接位于flex子元素(即container__listItem )内部时,这非常简单。 我可以使用以下代码用省略号(“…”)替换剪切的文本。

.example {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

But in this case I’ve put the content inside a div, which is wrapped by a container__listItem. Thus, the above solution won’t work. The article Flexbox and Truncated Text offers a solution. In the code below, the lines below the “updated” comments in each declaration block are the ones that deal with this problem:

但是在这种情况下,我将内容放入了div ,并由container__listItem包装。 因此,上述解决方案将不起作用。 文章Flexbox和截断的文本提供了一种解决方案。 在下面的代码中,每个声明块中“ updated”注释下面的行都是用于解决此问题的行:

.container__list {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  /* updated */
  min-width: 0;
}

.container__listItem {
  flex: 0 0 25%;
  padding: 10px 30px;
  /* updated */
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.container__listItem > div {
  color: #DB6356;
  /* updated */
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

将单个下拉部分限制为三列 (Limiting a Single Drop-down Section to Three Columns)

At this stage, the bulk of the work is now done. For this remaining section, I’ll add another drop-down section that I’ll force to be limited to three columns of items.

现在,大部分工作已经完成。 对于其余部分,我将添加另一个下拉部分,将其强制限制为三列项目。

As mentioned, I’ll replicate container__list twice and will use it in a new drop-down section called “Appliances”. This is done for demo purposes. In a real world example, you might have a generated list via JavaScript or using a back-end language.

如前所述,我将复制container__list两次,并将在新的名为“ Appliances”的下拉部分中使用它。 这是出于演示目的。 在真实的示例中,您可能通过JavaScript或使用后端语言生成了列表。

I’ll add a class of has-multi to tweak the user interface. Using this class I need to override a few properties.

我将添加一类has-multi来调整用户界面。 使用此类,我需要重写一些属性。

.container.has-multi .container__list {
  flex-basis: 33.333%;
}

.container.has-multi .container__list:not(:last-child) {
  border-right: solid 1px #f3f3f3;
  margin-right: 20px;
}

.container.has-multi .container__listItem {
  flex-basis: 100%;
}

Here I’ve set flex-basis to 33.333% as I want to display three sections in the container. I’ve changed only flex-basis, but the other 2 properties flex-grow and flex-shrink are already inherited from the single section code. This gives me flexibility when I have a container__list less than three. In the case of only two lists, the container__list items will grow and distribute space among themselves. That is, each will hold 50% of the total width.

在这里,我要将flex-basis设置为33.333%,因为我想在容器中显示三个部分。 我仅更改了flex-basis ,但是其他2个属性flex-growflex-shrink已从单个部分代码继承。 当container__list少于三个时,这给了我灵活性。 在只有两个列表的情况下, container__list项将增长并在它们之间分配空间。 也就是说,每个将占总宽度的50%。

Note that .container__listItem is set to flex-basis: 100%, which ensures a single column in the container__list. I could have used 50% to allow two columns in each section.

请注意, .container__listItem设置为flex-basis: 100% ,以确保container__list的单个列。 我本可以使用50%在每个部分中允许两列。

关于Mega菜单可用性的几点说明 (A Few Notes on Mega Menu Usability)

I’ve chosen mega menus as my example without much thought on its usability. Before using such a feature, I’ve provided a few resources that discuss the pros and cons.

我选择大型菜单作为示例,但并未对其可用性进行过多考虑。 在使用这种功能之前,我提供了一些资源,讨论了其优缺点。

In my opinion, mega menu navigation is useful for displaying all options and this style of navigation can be used effectively on e-commerce websites. I like Intel’s navigation.

我认为,大型菜单导航对于显示所有选项很有用,并且这种导航样式可以在电子商务网站上有效使用。 我喜欢英特尔的导航。

最后的话 (Final Words)

One thing to note is that the final mega menus from this tutorial aren’t fully responsive. The main menu bar will appear on smaller screens but the mega menus will not be available, with only the top-level links functional. For the purposes of this tutorial, this should suffice. Feel free to fork the demo and improve on this if you like.

需要注意的一件事是, 本教程的最终大型菜单没有完全响应。 主菜单栏将显示在较小的屏幕上,但大型菜单将不可用,仅具有顶级链接功能。 就本教程而言,这已足够。 如果愿意,可以随意分发演示并进行改进。

A mega drop-down menu navigation system is a decent way to demonstrate the power and simplicity of Flexbox, which I hope I have conveyed in this tutorial. As you can see, flexbox is useful for more than just centering content.

大型下拉菜单导航系统是展示Flexbox功能和简便性的一种不错的方式,我希望我已在本教程中传达了这一点。 如您所见,flexbox不仅对内容居中有用。

If you’ve used a different flexbox-based technique to build a mega menu system, feel free to tell us about it in the comments.

如果您使用了另一种基于Flexbox的技术来构建大型菜单系统,请随时在评论中告诉我们。

Update: I’ve built a responsive mobile-friendly version of these mega menus, which you can find in this CodePen demo.

更新:我已经为这些大型菜单构建了一个响应式的移动设备友好版本,您可以在此CodePen演示中找到该菜单

翻译自: https://www.sitepoint.com/building-mega-menus-flexbox/

vux flexbox使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值