下面是JavaScript代码的一个示例(在这个示例中), we use jQuery) 那 can be used to dynamically toggle the navigation menu between 扩大 和 collapsed mode, 基于用户点击导航切换图标:
有了这个,我们的导航菜单现在可以动态地展开或折叠. 伟大的.
We then need to extend our JavaScript code to add dynamic adjustment of these other 元素 as well when the nav toggle is clicked by the user:
好了,这样就行了.
Now let’s address the requirement of having some pages 那 hide the sub nav menu. 具体地说, we want the sub nav menu to be hidden when the user clicks the “users” icon in the main nav area.
< / div >
因此,首先,我们将创建一个新类“hidden”来应用 显示:没有
:
.隐藏的{
显示:没有;
}
And again, we’ll use JavaScript (jQuery) to apply the “hidden” CSS class to the #子导航
元素,当用户单击users图标时:
$(' #导航.fa-user”).On ('click', 函数() {
$(" #子导航”).toggleClass(隐含);
});
加上这个, #子导航
元素在用户点击“users”图标时被适当地隐藏, 但它所占据的空间仍未被使用 ,而不是其他元素扩展以利用空间 #子导航
元素.
为了得到想要的行为,我们隐藏了 #子导航
元素, we’ll employ one of the lesser known, yet highly useful, CSS selectors known as the 相邻兄弟选择器 .
相邻兄弟CSS选择器
的 相邻兄弟选择器 允许您指定两个元素, selecting only those instances of the second 元素 那 立即 follow the specified first 元素.
例如,下面的代码将只选择具有ID的元素 main
那 立即 跟在带有ID的元素后面 子导航
:
#子导航 + #{主要
保证金-左: 20 em;
}
的左边距 #主要
to 20em
当且仅当 它立即跟随显示的#子导航
.
然而,如果 #导航
是膨胀的(这导致 扩大
要添加到的类 #主要
同样,根据前面的代码,我们移动的左边距 #主要
25他们.
#子导航 + #主要.扩大{
保证金-左: 25 em;
}
而且,如果 #子导航
是隐藏的,我们移动左边的边距 #主要
一直到6em就在旁边 #导航
:
#子导航.隐藏+ #{主要
保证金-左: 6 em;
}
(Note: One disadvantage of using the 相邻兄弟选择器 is 那 it 为ces us to al道路s have #子导航
显示在DOM中,而不管它是否被显示.)
最后,如果 #子导航
是隐藏的 #导航
是展开的,我们设置左边距 #主要
at 11em
:
#子导航.Hidden + #主要.扩大{
保证金-左: 11 em;
}
这使我们能够在没有任何繁重的JavaScript代码的情况下将东西连接在一起, but we can also see how complicated this code can become if we add more 元素 to the page. 我们再次看到,使用CSS2, 很多 of hardcoding of 位置值 is needed in order to get things to work properly.
利用CSS3
CSS3 offers significantly enhanced 函数ality 和 layout techniques 那 make it much easier to use 和 much less reliant on hardcoded values. CSS3天生就支持更多的动态行为, 从这个意义上说, “可编程”. 让我们来看看与我们的用例相关的一些新功能.
CSS3 钙()
函数
新 CSS3 钙()
函数 可以用来动态计算CSS属性值(不过请注意, 支持不同 跨浏览器). 的表达式 钙()
函数 can be any simple expression combining the basic arithmetic operators (+
, -
, *
, /
),使用标准操作符优先规则.
的使用 钙()
函数可以帮助避免CSS2所需的许多值的硬编码. 在我们的例子中,这使我们能够更动态地实现CSS扩展. 例如:
#导航, #子导航{
位置:固定;
高度: calc(100% - 10em); /* replaces */
z - index: 20;
}
有了以上内容 高度
规范使用 钙()
函数,我们实现了与CSS2中相同的结果 上图:6 em
和 底部:4 em
, but in a much more flexible 和 adaptive 道路, without needing to hardcode 前
和 底
位置值.
CSS3 Flexbox布局
Flexbox 是CSS3 (不同浏览器的支持不同 ). 的 flexbox layout makes it simpler to arrange 元素 on a page in a 道路 那 behaves predictably across different screen sizes, 决议, 和设备. 因此,它在下列情况下特别有用 响应式网页设计 .
主要特点包括:
Positioning child 元素 is much easier 和 complex layouts can be achieved more simply 和 with cleaner code.
Child 元素 can be laid out in any direction 和 can have flexible dimensions to adapt to the 显示 space.
子元素自动扩展契约以适应可用的空闲空间.
Flexbox引入了自己独特的术语和概念. 其中一些包括:
Flex容器. 具有其 显示
属性设置为 flex
or inline-flex
哪个作为伸缩项的容器元素.
Flex项目. 伸缩容器中的任何元素. (Note: Text directly contained in a flex container is wrapped in an anonymous flex item.)
轴 . 每个flexbox布局都有 flex-directio
n 它指定了 主轴 伸缩项沿其布局. 的 十字轴 那么轴是否垂直于主轴.
行. Flex项目s can be laid out on either a single line or on several lines according to the flex-wrap
财产.
维. 高度和宽度的flexx等价物是 主要尺寸
和 交叉的大小
, which specify the sizes of the 主轴 和 十字轴 of the flex container分别.
OK, 简单介绍一下, 如果我们使用flexx布局,这里是我们可以使用的替代标记:
对于我们的示例用例, 我们的主布局(头部), 内容, 页脚)是垂直的, 所以我们将flexx设置为使用列布局:
.layout-flexbox {
显示:flex;
flex-direction:列;
}
虽然我们的主要布局是垂直的, 内容区域中的元素(nav, 子导航, 主)是水平布局的. 每个伸缩容器只能定义一个方向(i.e.,其布局必须是水平或垂直的). 因此, when the layout requires more than this (a common case being 为 an app layout), 我们可以将多个容器嵌套在一起, 每个都有不同的方向布局.
这就是为什么我们添加了一个额外的容器(我称之为 [
)包装 #导航
, #子导航
, #主要
. 这种方式, 整体布局可以是垂直的, 而内容区的内容可以水平布局.
现在,为了定位我们的伸缩项,我们将使用属性 flex
这是一个简写 flex: ;
. Those three flex properties are the ones 那 determine how our flex items distribute any free space remaining between them in the flow direction, 如下:
flex-grow: specifies how much an item can grow relative to the rest of the flexible items inside the same container
flex-shrink: specifies how an item can shrink relative to the rest of the flexible items inside the same container
flex-basis: 指定项的初始大小(i.e.(在它缩小或变大之前)
< / div >
设置 flex-grow
和 flex-shrink
两者都为零表示该项的大小为 固定 和 it will 不 grow or shrink to accommodate there being more or less free space available. 这就是我们对页眉和页脚所做的,因为它们有固定的大小:
#标题{
Flex: 0 0 5em;
}
#页脚{
Flex: 0 0 3em;
}
要让一个项目占用所有可用的空闲空间,请设置其 flex-grow
和 flex-shrink
值为1,并设置其 flex-basis
价值 汽车
. This is what we do 为 the 内容 area since we want it to take up all available free space.
就像我们之前说的,我们想要里面的项 [
为了按行方向排列,我们要加上 显示:flex
; 和 flex-direction:行;
. 这使得[成为一个新的flex容器 #导航
, #子导航
和“#主要.
这就是CSS的最终目的 [
:
.[{
显示:flex;
flex-direction:行;
Flex: 1 1 汽车; /* take up all available space */
边距:1em 0;
min-高度: 0; /* fixes FF issue with minimum 高度 */
}
在内容区域,两者都有 #导航
和 #子导航
有固定的大小,所以我们只需要设置 flex
相应的属性:
# nav {
Flex: 0 0 5em;
保证金-正确的: 1 em;
overflow-y:汽车;
}
#子导航{
Flex: 0 0 13em;
overflow-y:汽车;
保证金-正确的: 1 em;
}
(注意,我添加了 overflow-y:隐藏
to these CSS specifications to overcome 内容 exceeding 和 overflowing the container 高度. Chrome实际上不需要这个,但是FireFox需要.)
#主要
将占用剩余的空闲空间:
#{主要
Flex: 1 1 汽车;
overflow-y:汽车;
}
This all looks good, so now let’s add our dynamic behavior to this 和 see how 那 goes.
JavaScript与我们之前的相同(除了这里), 我们指定的CSS元素容器类是 layout-flexbox
而之前是 layout-classic
):
$('.layout-flexbox #导航”).(“点击”、“李.Nav-toggle ', 函数() {
$ (' # nav ').toggleClass(扩大);
});
我们加上 扩大
类转换为CSS如下:
# nav {
Flex: 0 0 5em; /* collapsed size */
保证金-正确的: 1 em;
overflow-y:汽车;
&.扩大{
flex: 0 0 10em; /* 扩大 size */
}
}
瞧!
Note 那 this time we don’t need to let other items know about the 宽度 change, 因为flexbox布局为我们处理了所有这些.
唯一剩下的就是把潜艇导航藏起来了. 你猜怎么着? That “just works” too, without any 额外的 changes, using the same JavaScript code as be为e. Flexbox knows about free space 和 it 汽车matically makes our layout work with no extra code. 很酷.
Flexbox also provides some interesting 道路s of centering both vertical 和 horizontal 元素. We realize here how important it is 为 a presentational language to include the 不ion of free space 和 how scalable our code can become using these sorts of techniques. On the other h和, the concepts 和 不ation here can take a bit more to master than classic CSS.
CSS3网格布局
如果Flexbox布局是在CSS3的前沿, 那么网格布局可以说是在其流血的边缘. W3C规范仍处于草案状态 浏览器支持相当有限 . (It’s enabled in Chrome through the “experimental 网络 Plat为m features” flag in chrome://flags ).
也就是说,我个人并不认为这个草案具有革命性. 相反,作为 HTML5设计原则 状态: 当一种做法在作者中已经很普遍的时候, 考虑采用它,而不是禁止它或发明新的东西.”
相应的, 基于标记的网格已经使用了很长时间, 所以现在CSS网格布局实际上只是遵循相同的范式, offering all of its benefits 和 much more in the presentation layer with no markup requirements.
一般的想法是有一个预定义的, 固定, 或者灵活的网格布局,我们可以定位我们的元素. 比如flexbox, it also works on the free space principle 和 allows us to define both vertical 和 horizontal “directions” in the same 元素, 哪个在代码大小和灵活性上有优势.
Grid layout introduces 2 types of grids; namely, 显式的 和 隐式的 . 为了简单起见,我们将重点放在显式网格上.
Like flexbox, Grid layout introduces its own unique set of terms 和 concepts. 其中一些包括:
网格容器. 具有其 显示
属性设置为 “grid” or “inline-grid” into which the contained 元素 are laid out by positioning 和 aligning to a predefined grid (显式的 mode). 的 grid is an intersecting set of horizontal 和 vertical grid lines 那 divide the grid container’s space into grid cells. 的re are two sets of grid lines; one 为 defining the columns 和 one orthogonal to it 为 defining the rows.
网格跟踪. 网格:两条相邻网格线之间的空间. 每个网格轨道被分配一个大小函数, 哪个控件控制列或行可以增长多宽或多高, 也就是它的边界网格线之间的距离.
网格单元. 两个相邻行和两个相邻列网格线之间的空间. It is the smallest unit of the grid 那 can be referenced when positioning grid items.
灵活的长度. 指定的维度 fr
单元,它表示网格容器中可用空间的一小部分.
< / div >
如果我们使用网格布局,这里是我们可以使用的替代标记:
注意,在这个布局中,我们这样做 不 内容区域需要一个额外的包装器,就像我们为flexbox所做的那样, since this type of layout allows us to define 元素 space designation in both directions in the same grid container.
现在让我们深入了解CSS:
.布局格局{
显示:网格;
网格模板列:汽车 0 汽车 1em 1fr;
网格模板行:5em 1em 1em 3em;
}
我们定义 显示:网格;
在我们的集装箱上. 的 grid-template-columns
和 grid-template-rows
每个属性都被指定为网格轨道之间的空格列表. In other words, those values are 不 the position of the grid lines; rather, they represent the 空间量 两轨之间.
注意,测量单位可以指定为:
一个长度
网格容器大小的百分比
对所占列或行内容的测量
网格中自由空间的一小部分
所以, 网格模板列:汽车 0 汽车 1em 1fr;
我们将有:
1个轨道定义2列 汽车
宽度(#导航
空间)
0的边距 #子导航
is at the 元素 level, as it can be present or 不, this 道路 we avoid having double gutter)
1个轨道定义2列 汽车
宽度(#子导航
空间)
1沟槽 1em
1轨道使用 1fr
为 #主要
(将占用所有剩余空间)
这里我们大量使用 汽车
轨道的值, which allows us to have dynamic columns where the position 和 size of lines are defined by their maximum 内容. (因此,我们需要指定的尺寸 #导航
和 #子导航
元素,我们很快就会讲到.)
类似地,对于我们已知的行线 网格模板行:5em 1em 1em 3em;
这就是我们的 #头
和 #页脚
to be 固定 和 all 元素 between to use the remaining free space while using 1em
排水沟.
Now let’s see how we place the actual 元素 to be 定位 into our defined grid:
#标题{
格柱:1 / 6;
格列:1 / 2;
}
#页脚{
格柱:1 / 6;
格列:5 / 6;
}
#{主要
格柱:5 / 6;
格列:3 / 4;
overflow-y:汽车;
}
This specifies 那 we want our header to be between grid line 1 和 6 (full 宽度), 在网格线1和2之间. 页脚也一样,但在最后两行之间(而不是前两行). And the main area is set appropriately 为 the space it is supposed to occupy.
请注意 grid-column
和 行
属性是指定的简写 grid-column-start
/ grid-column-end
和 行-start
/ 行-end
分别.
好,回到 #导航
和 #子导航
. 因为我们之前 #导航
和 #子导航
进入轨道与自动值, 我们需要指定这些元素的宽度(对于扩展模式也是如此), 我们只需要改变它的宽度,网格布局会处理好剩下的部分).
# nav {
宽度:5 em;
格柱:1 / 2;
格列:3 / 4;
&.扩大{
宽度:10 em;
}
}
#子导航{
格柱:3 / 4;
格列:3 / 4;
宽度:13 em;
轨道的边距为0,所以在这里添加边距*/
保证金-左: 1 em;
}
现在我们可以切换 #导航
还有隐藏/移除 #子导航
一切都很完美! 网格布局也允许我们为我们的线条使用别名, so eventually changing grids won’t break out code as it’s mapped to a name 和 不 a grid line. Definitely looking 为ward to this being more widely supported by more browsers.
结论
即使使用经典的CSS技术, there’s much more 那 can be accomplished than many web developers realize or take advantage of. 也就是说, much of this can be quite tedious 和 can involve hardcoding of values repeatedly throughout a style sheet.
CSS3 has begun to deliver much more sophisticated 和 flexible layout techniques 那 are 更容易编程 并且避免了以前的CSS规范的许多乏味之处.
Mastering these techniques 和 paradigms – both 为 CSS2 和 CSS3 – is essential to leveraging all 那 CSS has to offer in order to optimize both the user’s experience 和 the quality of your code. This article really just represents the tip of the iceberg of all there is to learn 和 all 那 can be accomplished with the power 和 flexibility of CSS. 试试吧!
< / div >< / div >< / div >
< / div >
标签 < / div >< / div >< / div >< / div >
聘请Toptal这方面的专家.< / div >
现在雇佣 < / div >< / div >
< / div >