Responsive design is not about removing and shrinking web page components as the browser narrows: it’s about making the most of the space available in the viewport. Sometimes that means merging components, rather than taking them away. A prime example is the columnar layout of the kind shown above. On wide screens, the columns appear side-by-side:
自适应设计并不是要随着浏览器的缩小而删除和缩小网页组件,而是要充分利用视口中的可用空间。 有时,这意味着合并组件,而不是将其删除。 一个很好的例子是上面显示的那种柱状布局。 在宽屏幕上,各列并排显示:
But as the viewport narrows, it may make sense to merge columns A and C together:
但是随着视口变窄,将列A和C合并在一起可能是有意义的:
There are scripts (such as the excellent appendAround) that can help create this, but they all have similar disadvantages:
有一些脚本(例如出色的appendAround )可以帮助创建此脚本,但是它们都有类似的缺点:
- Framework dependencies. 框架依赖性。
- The setup of “catcher” containers for moved elements can be confusing. 用于移动元素的“捕手”容器的设置可能会造成混淆。
The reality is, you can achieve your own custom solution in just a half-dozen lines of code, as demonstrated here.
现实情况是,您只需使用六行代码即可实现自己的自定义解决方案,如此处所示。
HTML和CSS (The HTML & CSS)
The markup for this example is pretty straightforward:
此示例的标记非常简单:
<div id="wrapper">
<nav>A</nav>
<main>B</main>
<aside>C</aside>
</div>
I’ll place the elements side-by-side and the same height using flexbox, although many other possibilities exist, including display: table
.
尽管存在许多其他可能性,包括display: table
,但我将使用flexbox并排放置相同高度的元素。
#wrapper {
display: flex; width: 100%;
}
#wrapper > * {
flex: .5;
}
#wrapper nav {
background: hsl(90, 50%, 80%);
display: flex;
flex-direction: column;
}
#wrapper main {
background: hsl(180, 50%, 80%); flex: 2;
}
#wrapper aside {
background: hsl(270, 50%, 80%);
}
#wrapper aside, #wrapper main {
min-width: 150px;
}
I’ve given each of the elements an HSL background to keep them distinct; the <main>
element is set to be 4× the width of the other two via the flex
property. As the <nav>
element will be taking the <aside>
element as a guest when the viewport narrows, I’ve set it to display as a column. This won’t disturb the content of the element, but will set the original content above the <aside>
when the two are merged.
我为每个元素提供了HSL背景,以使其与众不同。 通过flex
属性将<main>
元素设置为其他两个元素的宽度的4倍。 由于<nav>
元素将在视口变窄时将<aside>
元素用作来宾,因此我将其设置为显示为列。 这不会打扰元素的内容,但是当两者合并时,会将原始内容设置为<aside>
以上。
使用JavaScript合并元素 (Merging Elements With JavaScript)
At the end of the page, we start our script by identifying the elements that will be affected, together with the conditions for switching:
在页面的最后,我们通过识别将受影响的元素以及切换条件来启动脚本:
var nav = document.querySelector("#wrapper > nav"),
aside = document.querySelector("#wrapper > aside"),
wrapper = document.getElementsById("wrapper"),
tablet = window.matchMedia("screen and (max-width: 800px)");
The matchMedia
expression sets the viewport width at which we want to merge the elements. This movement and merge is controlled by a single function:
matchMedia
表达式设置我们要合并元素的视口宽度。 此移动和合并由单个功能控制:
function combinator(state){
aside.remove();
if (state.matches) {
nav.appendChild(aside);
} else {
wrapper.appendChild(aside);
}
}
You could also use the more traditional JavaScript remove method if you needed IE support.
如果需要IE支持,也可以使用更传统JavaScript删除方法 。
This function effectively “pops” the <aside>
element in and out of <nav>
at the breakpoint set by the matchMedia
variable. We just have to call it:
该功能有效地将<aside>
元素“弹出”在matchMedia
变量设置的断点处的<nav>
中。 我们只需要调用它:
combinator(tablet);
However, this will only call the function once, during the initial page load. We must also add a listener to react to any subsequent changes to the viewport:
但是,这将在初始页面加载期间仅调用一次函数。 我们还必须添加一个侦听器,以对视口的任何后续更改做出React:
tablet.addListener(combinator);
融合合并 (Blending The Merge)
Once the merge is complete, the shifted element should take some of the styles of its new parent. I would suggest adding a single-line CSS declaration:
合并完成后,转移的元素应采用其新父元素的某些样式。 我建议添加单行CSS声明:
.wrapper nav > aside {
width: 100%; background: inherit;
}
Note that this declaration doesn’t have to placed inside an @media query, since we can usually assume there’s no other condition in which an <aside>
element might be placed inside <nav>
.
请注意,此声明不必放在@media查询中,因为我们通常可以假设没有其他条件可以将<aside>
元素放置在<nav>
。
Of course there are many other possibilities for this technique; I’ll explore more in future articles.
当然,这种技术还有许多其他可能性。 我将在以后的文章中进一步探讨。
翻译自: https://thenewcode.com/949/Merging-Responsive-Page-Elements-with-JavaScript