新的主题采用最强大的css布局方式——grid布局

最近新发现一个hugo主题,https://github.com/zzossig/hugo-theme-zzo,觉得好看便改成了wordpress主题用到了自己的博客上,然后发现这个主题的css样式写的我有点看不懂,原来是用的grid布局,了解了一下发现这个布局方式好强大啊

使用Flex弹性布局解决浮动元素无法将高度设为100%

很久没认真的写过CSS了,今天发现一个问题,是我这个网站主题上的,这个主题很老,用的table布局,给各种宽度的设备都设置了不同的样式,看的我真的很难受,之前是这样的:

给不同宽度的设备设置了不同的元素宽度,这是很久以前的写法,我刚开始是将它全部改成百分比浮动写法,当然这种方法也没有特别高级,但是也可以省掉很多重复代码
然后就牵涉到一个问题:**如果将浮动元素的高度设置为父元素的高度?**
我在 [css – 让浮动元素高度等于父元素高度 – SegmentFault 思否](https://segmentfault.com/q/1010000004516026) 中看到一个解决办法,是将浮动元素再套一个元素然后设置内元素绝对定位即可,但是这种方法有一个弊端就是,要设置为父元素高度的浮动元素不能高于另一个浮动元素,否则无法显示,试了很多种办法的确如此
说实话用上面那种办法我已经很不情愿了,我以前可从来不用position的,更不说absolute这种将元素脱离于文本流之外的写法我是很鄙夷的
怎么办呢?当然,如果你硬要在float上解决也不是没办法,随便加个有高度的元素或者设置另一个元素的min-width都行,但是我怎么可能用这种恶心的写法呢
然后我就想到这**完全可以用css3的flex弹性布局**,那个问题是2016年提的,也许是那时候flex布局还不够普遍把
很多时候不是技术不好,完全是脑子不转弯,不愿意去尝试新事物,唉,我也是如此,即便很早就会使用flex,但遇到问题还是喜欢先用自己经常用的方法去解决,放着更好的方案不用

我从来没用过的 table 布局

今天看到一个WP主题,最后更新日期是2014年,本来一开始还没发现,写着写着,居然看到 父子元素 之间的 margin 外边距居然可以互相影响,然后发现这份主题用的是我从来没见过的 table 布局。
事实上,在我很早的时候,或者说还没有接触网络的时候,我用过一个叫 Frontpage 的“设计”网页的软件,它之前是包含在微软office 2003里面的,但是在后来就没有更新了,所以最新的版本是 frontpage 2003,我记得用它来做网页的时候,全部采用的是表格布局。还有我后来接触的,比 frontpage 要高级的多 dreamweaver 也是用的 table 布局,不过当时的我并没有过多的去关注代码,纯粹是觉得好玩而已。
在后来,我写网页的时候就一点也没用过这个“老古董”了,现在我甚至一看到各种 td、tr就烦,我认为这样太复杂了,我到现在都不知道到底是 td 包含着 tr 还是 tr 包着 td。我极少数情况会在网页中用到表格,除非是这个东西是真的要用表格呈现出来,那么我也可以用 li 加个 inline-block 去搞定,除非是真的要用,否则我根本不会去写 表格 的样式,就算要用,我也会直接去复制一个 现成的样式。
所以,在我刚看到那个主题的时候,我才回想起来,原来若干年前 table 还可以用来布局!我在之前很长一段时间里认为这只不过是用来写表格且只会出现在各种上年头的网站里。
当然,我相信现在依然有网站在使用 table 布局,因为一个技术的彻底消亡是需要很长的时间的,就像现在我依旧还能在很多网站看到 flash 技术,一些视频网站依旧使用 flash 播放器。
也许多年以后,会有更加先进的技术来取代整个web技术,这也说不定呢

CSS框架——bulma

又是闲得无聊,把博客重新写了一遍,刚开始使用的bootstrap框架,也是做出了现在这个样子,但是感觉不怎么好看,所以又找了找其它框架,然后就找到了这个——Bulma,看了看还不错,就用它把主题重新写了一遍,下面说说我是如何使用这个框架的:

布局

首先应该先把网站的整体结构先布置好,像我这个博客的话,就会需要一个顶部nav、底部的footer、中间的部分根据情况是单栏还是双栏则需要加个sidebar

我这里先以单栏为例,则得到的HTML结构是这样的:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Hello Bulma!</title>
</head>
<body>
  <nav class="navbar">
    <!-- nav -->
  </nav>
  <section class="section">
    <!-- content -->
  </section>
  <footer>
    <!-- footer -->
  </footer>
</body>
</html>

navbar

绝大多数的网站都需要一个顶栏,navbar就是bulma的一个组件,一个navbar分为两部分,navbar-brandnavbar-menu,navbar-brand为整个网站的Title或者LOGO。

<nav class="navbar" role="navigation" aria-label="main navigation">
  <div class="navbar-brand">
    <!-- navbar items, navbar burger... -->
  </div>
  <div class="navbar-menu">
    <!-- navbar start, navbar end -->
  </div>
</nav>

navbar-menu在移动端中会隐藏起来,可以通过一个按钮来点击显示,这就需要在navbar-brand中添加一个button

<button class="button navbar-burger" data-target="navMenu">
  <span></span>
  <span></span>
  <span></span>
</button>

因为bulma不包含js代码,所以这段代码需要自己来写了,官网也给了一个例子,其实很简单,如果使用了JQuery的话:

$(document).ready(() => {
  $(".navbar-burger").click(() => {
    $(".navbar-menu").toggle();
  })
})

navbar-menu分为navbar-startnavbar-end其中一个居左一个居右

<div class="navbar-menu">
  <div class="navbar-start">
    <!-- navbar items -->
  </div>
  <div class="navbar-end">
    <!-- navbar items -->
  </div>
</div>

而navbar上面的项目只需要添加一个样式navbar-item类即可。

<div class="navbar-start">
  <a class="navbar-item">
    Home
  </a>
</div>

navbar默认白色,可以更换颜色,具体可以使用的样式有is-primaryis-linkis-infois-successis-warningis-dangeris-blackis-darkis-lightis-white

效果如图所示:

关于navbar的更多内容可以查看Navbar | Bulma: a modern CSS framework based on Flexbox

section

bulma使用section来区分不同的模块,即在nav和footer中间的内容应该为一个section或者多个section,而且使用.section样式。

container

在bulma中,无论在navbarsectionfooter中,都需要立即放一个class为container的div,来让内容居中显示。

content

这个class类至关重要,因为在bulma中,除了在这个类之外的所有文本都是一样的大小,所以在文章主体中必须添加这个类,当然很简单的方法就是像我这样在section中直接加上这个类就好了。

footer

footer作为页面的页脚,添加一个class为footer的footer标签即可,footer类的样式为

.footer {
    background-color: whitesmoke;
    padding: 3rem 1.5rem 6rem;
}

比较大。

关于更多布局的方法可以参考我博客的样式和bulma官网的样式。

响应式

Bulma 的网格体系基于 Flex 布局。需要使用columns来指定容器,使用column指定项目。

bulma和bootstrap一样,都支持12网格体系,你可以像这样来表示

  • is-2
  • is-3
  • is-4
  • is-5
  • is-6
  • is-7
  • is-8
  • is-9
  • is-10
  • is-11

或者你可以像我一样使用分数表示:

  • 四分之三:is-three-quarters
  • 四分之一: is-one-quarter
  • 三分之二:is-two-thirds
  • 三分之一:is-one-third
  • 二分之一:is-half
  • 五分之四:is-four-fifths
  • 五分之三:is-three-fifths
  • 五分之二:is-two-fifths
  • 五分之一:is-one-fifth

具体使用实例:

<div class="container">
  <div class="columns">
    <div class="column is-two-thirds">content</div>
    <div class="column is-one-third">sidebar</div>
  </div>
</div>

例如在我的主页中,左侧的文章列表使用了is-two-thirds,右边的sidebar使用了is-one-third,这与使用is-9is-3的效果是一样的,也等同于bootstrap中的col-md-9col-md-3

自定义

因为下载的bulma压缩包里带有sass源文件,而Jekyll默认就支持编译SASS,所以我直接引用的源码包里的sass文件,再把一些没用到的组件注释掉,省了差不多一半的大小。

使用Node构建项目时参考Customize Bulma Bulma: a modern CSS framework based on Flexbox

参考&&推荐浏览

CSS3计算函数——calc

calc是英文单词calculate(计算)的缩写,是css3的一个新增的功能,我们可以使用calc函数给任何长的值进行计算。

calc的作用:

在进行页面布局时,尤其是在普遍使用响应式布局的今天,我们更多的不是使用传统的px长度值,而是使用百分比、em、rem等单位值。

在很多时候,我们只知道一个百分值,但其他值又是px之类的值,这就是难点,我们不可能去计算每次百分比的值到底是多少,但随着CSS3的出现,其中利用box-sizing来改变元素的盒模型类型实使实现效果,但今天我们学习的calc()方法更是方便。

语法说明:

calc()函数支持 "+", "-", "*", "/" 运算;
calc()函数使用标准的数学运算优先级规则;
需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);

来看一个很简单的例子

  <div class="wrapper">
    <div class="content">
    </div>
  </div>

然后我们向其添加CSS

.wrapper {
  width: 300px;
  background: red;
}
.content {
  width: 100%;
  background: yellow;
  height: 50px;
}

这时的效果很简单,content完全遮住了wrapper

第二步,在content上添加borderpadding

这一步很棘手的事情来了,在content上添加10px的内距padding,同时添加5px的border:

.wrapper {
  width: 300px;
  background: red;
}
.content {
  width: 100%;
  background: yellow;
  height: 50px;
  padding: 10px;
  border: 5px solid green;
}

为了更加清楚直观的发现问题,我给wrapper上下加一个3px的内边距。

.wrapper {
  width: 300px;
  background: red;
  padding: 3px 0;
}
.content {
  width: 100%;
  background: yellow;
  height: 50px;
  padding: 10px;
  border: 5px solid green;
}

我们发现,content的总长度(width+border+padding)超过了容器wrapper的长度,content出来了。

但是我们给content的width设定为100%是不想让他撑破父容器的,这个时候我们可以给content加个box-sizing,设定为border-box

但是今天我们不谈这个,我们用calc去实现。

我们知道总宽度是100%,在这个基础上减去boder的宽度(5px * 2 = 10px),在减去padding的宽度(10px * 2 = 20px),即”100% – (10px + 5px) * 2 = 30px” ,最终得到的值就是content的width值:

.wrapper {
  width: 300px;
  background: red;
  padding: 3px 0;
}
.content {
  background: yellow;
  height: 50px;
  padding: 10px;
  border: 5px solid green;
  width: 90%; /*写给不支持calc()的浏览器*/
  width:-moz-calc(100% - (10px + 5px) * 2);
  width:-webkit-calc(100% - (10px + 5px) * 2);
  width: calc(100% - (10px + 5px) * 2);
}

这样一来,通过calc()计算后,content不在会超出其容器wrapper的宽度.