页面布局和编写的解决方案
概述
这几天写了一些PC端页面,有了一些问题和解决方案记录下来,供以后开发时参考,相信对其他人也有用.
之前参考过Alloyteam代码规范和NEC规范,但是写的时候感觉有些地方不太对劲,参考B站或者网易的一些网站的时候也发现和他们的规范不一样,所以想把相关东西记下来.
总的规则
写PC端页面的时候,都要遵循一些总的规则,它们是:
- 兼容不同屏幕大小,但并不需要兼容太小的屏幕比如手机端,因为手机端网页分开写.
- 易读,代码是写给别人看的,也是需要后期维护的,从html,css到js结构和命名上面,都需要很易读.
- 标签语义化,为了方便SEO,也为了使页面结构更加健壮易读.
- 其它(待研究).
页面布局
需求1:给你一个页面,怎么布局?
从大的范围来说,一个页面一般由这几样东西构成:
- 一个导航栏,用header或者nav标签.
- 一些小组件或者一些hide的内容,用div+类名或者id名编写.
- 一个主体,用main标签.
- 一个页脚,用footer标签.
注意:能用标签的尽量用标签;如果要兼容IE<9的浏览器的话,还是写成div的class形式.
然后具体到小的方面,一个主体main标签一般包含如下东西:
- page小页面,可以用page123或者wrap123表示.
- content主要内容,可以用cont表示.这个非常重要,每个小页面必须有一个cont,这是展现给大家看的,而且需要兼容不同屏幕并且居中,这个解决方案等会再说.
- 一些logo等绝对定位的内容.这些内容分2类,一类是尺寸小的图片或者组件,不随屏幕大小而变化的,比如各种logo,另一类是尺寸大的图片或者组件,他们如果不随屏幕大小而变化就会遮住主要内容cont,所以需要随着屏幕大小而变化,这个解决方案等会儿说.
最后到更小的方面,cont的内容需要有明确的语义化标签,具体有如下规则:
- 部分有标题性质的文字可以用h4或者h5包裹而不是用span包裹.
- 除非特殊需求,ul, img, a一般都不需要用div包裹.
- 并列的元素,能用ul就用ul;文字能用p就用p.
- 由于img标签会阻塞网页内容的加载,而background-image会等到网页内容加载完成之后再加载,所以一般都用background-image,如果实在因为SEO的关系,img标签太重要,比如logo和二维码等,就用img标签.(另外如果有懒加载,也可以用img标签,比如B站)
需求2:cont怎么兼容不同屏幕?
css如下设置即可:
max-width: 980px;
margin: 0 auto;
position: relative;
max-width的取值需要看cont的内容的具体宽度,应该刚好等于cont内容的具体宽度.
如果需要占据一整页,则设置height: 942px即可.
需求3:绝对定位内容的位置怎么随屏幕大小而变化?
给绝对定位的内容加一层wrap,绝对定位内容的位置不变,给这层wrap加入如下css属性:
position: absolute;
width: 1920px;
height: 950px;
top: 0;
left: 50%;
margin: 0 0 0 -960px;
需求4:cont里面的内容用不用绝对定位?
如果是占据一行一行的内容,那肯定不用绝对定位;而如果是不规则的图片,那么就用绝对定位.(为什么不用相对定位?其实相对定位就是考虑了尺寸的绝对定位,本质与绝对定位没有什么差别,所以可以使用绝对定位.)
class命名规范
需求1:class用不用树命名?
这个问题害了我很长时间.因为Alloyteam规范和NEC规范都推荐使用树命名,就是子标签用父标签+"-"+内容来命名.但是据我观察大多数网站,都不是这样命名的,都是用功能来命名,比如一个cont1的父标签有一个list子标签,那么这个list的class就用list来命名,不用cont1-list命名.一方面是比较好辨认,另一方面也是因为less比较方便书写.
想了很久,只有一种情况用树命名,就是有很多层不同的嵌套,而且功能的英文名很长....
需求2:用功能的话,怎么命名?
总结一下经常用到的命名法则:
- page123, cont的命名自不必多说.
- 并列的元素,如果没有特别需求都不命名,有特别需求,用item123命名.
- 列表用list,按钮用butt等.
需求3:嵌套层数太多了怎么办?
省略中间嵌套即可.比如.widescreen下有一个.vd-list,再下面有一个li,再下面有一个.preview,正常嵌套是.widescreen .vd-list li .preview
,可是超过了4层,解决方法是把.preview嵌套在.widescreen下面即可,或者给li定义一个class,比如haha,然后用这个嵌套.widescreen .haha .preview
.
需求4:多个div选中状态各不相同,怎么写css和html?
不需要对每一个div加上不同的class,再加上不同的选中class,直接在div下的class里面嵌套&.on,然后设置不同的选中状态即可.(也就是说,选中状态加一个on这个class即可)
需求5:为了后期维护,有哪些class命名的禁止事项?
(1)css中禁止在两个不同的地方调用相同位置的class,解决方案:重新加一个class.
(2)禁止出现page+内容的命名,比如page-butt2.规范及解决方案如下:
规范:有嵌套或者嵌套多的,大的用page+功能命名,小的直接内容命名(因为有嵌套);没嵌套或者嵌套少的,直接用page+功能命名,并列的允许用page+功能+内容命名.总之就是要精简命名但又易读.
解决方案:
- 它的嵌套加上page-butt,然后给它加上item2(或者内容).
- 改成page+功能,比如page-start
css排序
css或者less需要按一定的顺序编写,具体参照Alloyteam代码规范里面的顺序.
可以使用ST3的CSScomb插件一键排序.先安装好CSScomb插件,然后在CSScomb的用户设置里面加入如下代码即可.快捷键是CTRL + SHIFT + C.
{
"config": {
"remove-empty-rulesets": true,
"always-semicolon": true,
"color-case": "lower",
"block-indent": " ",
"color-shorthand": true,
"element-case": "lower",
"eof-newline": true,
"leading-zero": false,
"quotes": "double",
"sort-order-fallback": "abc",
"space-before-colon": "",
"space-after-colon": " ",
"space-before-combinator": " ",
"space-after-combinator": " ",
"space-between-declarations": "\n",
"space-before-opening-brace": " ",
"space-after-opening-brace": "\n",
"space-after-selector-delimiter": "\n",
"space-before-selector-delimiter": "",
"space-before-closing-brace": "\n",
"strip-spaces": true,
"tab-size": true,
"unitless-zero": true,
"vendor-prefix-align": true,
"sort-order": [
[
"display",
"visibility",
"float",
"clear",
"overflow",
"overflow-x",
"overflow-y",
"clip",
"zoom"
],
[
"table-layout",
"empty-cells",
"caption-side",
"border-spacing",
"border-collapse",
"list-style",
"list-style-position",
"list-style-type",
"list-style-image"
],
[
"-webkit-box-orient",
"-webkit-box-direction",
"-webkit-box-decoration-break",
"-webkit-box-pack",
"-webkit-box-align",
"-webkit-box-flex"
],
[
"position",
"top",
"right",
"bottom",
"left",
"z-index"
],
[
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"-webkit-box-sizing",
"-moz-box-sizing",
"box-sizing",
"border",
"border-width",
"border-style",
"border-color",
"border-top",
"border-top-width",
"border-top-style",
"border-top-color",
"border-right",
"border-right-width",
"border-right-style",
"border-right-color",
"border-bottom",
"border-bottom-width",
"border-bottom-style",
"border-bottom-color",
"border-left",
"border-left-width",
"border-left-style",
"border-left-color",
"-webkit-border-radius",
"-moz-border-radius",
"border-radius",
"-webkit-border-top-left-radius",
"-moz-border-radius-topleft",
"border-top-left-radius",
"-webkit-border-top-right-radius",
"-moz-border-radius-topright",
"border-top-right-radius",
"-webkit-border-bottom-right-radius",
"-moz-border-radius-bottomright",
"border-bottom-right-radius",
"-webkit-border-bottom-left-radius",
"-moz-border-radius-bottomleft",
"border-bottom-left-radius",
"-webkit-border-image",
"-moz-border-image",
"-o-border-image",
"border-image",
"-webkit-border-image-source",
"-moz-border-image-source",
"-o-border-image-source",
"border-image-source",
"-webkit-border-image-slice",
"-moz-border-image-slice",
"-o-border-image-slice",
"border-image-slice",
"-webkit-border-image-width",
"-moz-border-image-width",
"-o-border-image-width",
"border-image-width",
"-webkit-border-image-outset",
"-moz-border-image-outset",
"-o-border-image-outset",
"border-image-outset",
"-webkit-border-image-repeat",
"-moz-border-image-repeat",
"-o-border-image-repeat",
"border-image-repeat",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"width",
"min-width",
"max-width",
"height",
"min-height",
"max-height"
],
[
"font",
"font-family",
"font-size",
"font-weight",
"font-style",
"font-variant",
"font-size-adjust",
"font-stretch",
"font-effect",
"font-emphasize",
"font-emphasize-position",
"font-emphasize-style",
"font-smooth",
"line-height",
"text-align",
"-webkit-text-align-last",
"-moz-text-align-last",
"-ms-text-align-last",
"text-align-last",
"vertical-align",
"white-space",
"text-decoration",
"text-emphasis",
"text-emphasis-color",
"text-emphasis-style",
"text-emphasis-position",
"text-indent",
"-ms-text-justify",
"text-justify",
"letter-spacing",
"word-spacing",
"-ms-writing-mode",
"text-outline",
"text-transform",
"text-wrap",
"-ms-text-overflow",
"text-overflow",
"text-overflow-ellipsis",
"text-overflow-mode",
"-ms-word-wrap",
"word-wrap",
"-ms-word-break",
"word-break"
],
[
"color",
"background",
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
"background-color",
"background-image",
"background-repeat",
"background-attachment",
"background-position",
"-ms-background-position-x",
"background-position-x",
"-ms-background-position-y",
"background-position-y",
"-webkit-background-clip",
"-moz-background-clip",
"background-clip",
"background-origin",
"-webkit-background-size",
"-moz-background-size",
"-o-background-size",
"background-size"
],
[
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"opacity",
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
"-ms-interpolation-mode",
"-webkit-box-shadow",
"-moz-box-shadow",
"box-shadow",
"filter:progid:DXImageTransform.Microsoft.gradient",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
"text-shadow"
],
[
"-webkit-transition",
"-moz-transition",
"-ms-transition",
"-o-transition",
"transition",
"-webkit-transition-delay",
"-moz-transition-delay",
"-ms-transition-delay",
"-o-transition-delay",
"transition-delay",
"-webkit-transition-timing-function",
"-moz-transition-timing-function",
"-ms-transition-timing-function",
"-o-transition-timing-function",
"transition-timing-function",
"-webkit-transition-duration",
"-moz-transition-duration",
"-ms-transition-duration",
"-o-transition-duration",
"transition-duration",
"-webkit-transition-property",
"-moz-transition-property",
"-ms-transition-property",
"-o-transition-property",
"transition-property",
"-webkit-transform",
"-moz-transform",
"-ms-transform",
"-o-transform",
"transform",
"-webkit-transform-origin",
"-moz-transform-origin",
"-ms-transform-origin",
"-o-transform-origin",
"transform-origin",
"-webkit-animation",
"-moz-animation",
"-ms-animation",
"-o-animation",
"animation",
"-webkit-animation-name",
"-moz-animation-name",
"-ms-animation-name",
"-o-animation-name",
"animation-name",
"-webkit-animation-duration",
"-moz-animation-duration",
"-ms-animation-duration",
"-o-animation-duration",
"animation-duration",
"-webkit-animation-play-state",
"-moz-animation-play-state",
"-ms-animation-play-state",
"-o-animation-play-state",
"animation-play-state",
"-webkit-animation-timing-function",
"-moz-animation-timing-function",
"-ms-animation-timing-function",
"-o-animation-timing-function",
"animation-timing-function",
"-webkit-animation-delay",
"-moz-animation-delay",
"-ms-animation-delay",
"-o-animation-delay",
"animation-delay",
"-webkit-animation-iteration-count",
"-moz-animation-iteration-count",
"-ms-animation-iteration-count",
"-o-animation-iteration-count",
"animation-iteration-count",
"-webkit-animation-direction",
"-moz-animation-direction",
"-ms-animation-direction",
"-o-animation-direction",
"animation-direction"
],
[
"content",
"quotes",
"counter-reset",
"counter-increment",
"resize",
"cursor",
"-webkit-user-select",
"-moz-user-select",
"-ms-user-select",
"user-select",
"nav-index",
"nav-up",
"nav-right",
"nav-down",
"nav-left",
"-moz-tab-size",
"-o-tab-size",
"tab-size",
"-webkit-hyphens",
"-moz-hyphens",
"hyphens",
"pointer-events"
]
]
}
}
其它
其实我上面的这些心得都只适用于只有一个竖条cont的情况,如果有2个以上竖条cont的时候怎么布局呢?比如一个主要内容+一个侧栏.
方案一可以把侧栏写在cont里面,然后再给侧栏加一个绝对定位(慕课网这么做的);方案二可以给侧栏一个max-width
和一个float: right;
,让它在屏幕宽度变化的时候自动飘到下面去,然后用@media改变它的宽度(B站,掘金是这么做的).
网上有人说用flex(待研究)...