页面架构HTML+CSS ●▽● 各种布局各种实现

CSS Reset

1.作用

(1)清除浏览器默认样式
(2)全局样式定义

2.特别注意

(1)项目开发初期就定义好
(2) reset.css 在引入的时候一定要放在第一位
(3)不同的产品 reset.css不一样

3.table合并边框间距

  table {
  border-collapse: collapse; // 合并边框
  border-spacing: 0; //边框间距。当 `border-collapse` 值为 `seperate` 时生效

}

4.一个并不完整也并不通用的reset.css样例

      html,body,h1,h2,h3,h4,h5,h6,div,dl,dt,dd,ul,ol,li,p,blockquote,pre,hr,figure,table,caption,th,td,form,fieldset,legend,input,button,textarea,menu{margin:0;padding:0;}
    header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block;}
    table{border-collapse:collapse;border-spacing:0;}
    caption,th{text-align:left;font-weight:normal;}
    html,body,fieldset,img,iframe,abbr{border:0;}
    i,cite,em,var,address,dfn{font-style:normal;}
    [hidefocus],summary{outline:0;}
    li{list-style:none;}
    h1,h2,h3,h4,h5,h6,small{font-size:100%;}
    sup,sub{font-size:83%;}
    pre,code,kbd,samp{font-family:inherit;}
    q:before,q:after{content:none;}
    textarea{overflow:auto;resize:none;}
    label,summary{cursor:default;}
    a,button{cursor:pointer;}
    h1,h2,h3,h4,h5,h6,em,strong,b{font-weight:normal;}
    del,ins,u,s,a,a:hover{text-decoration:none;}
    body,textarea,input,button,select,keygen,legend{font:12px/1.14 arial,simsun;color:#333;outline:0;}
    body{background:#fff;}
    a,a:hover{color:#333;}

布局解决方案

居中布局

1.水平居中

父元素和子元素宽度未知。

  <div class="parent">
  <div class="child">child</div>
</div>

要达到的效果是这样:

方法一:flex + justify-content

主要代码:

  .parent { 
  display: flex;
  justify-content: center;
}

没啥好解释,直接看 神奇的flex实现栗子 吧 (~ ̄▽ ̄)~

方法二:absolute + transform

主要代码:

  .parent { position: relative; }
.child { 
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}

原理是: left: 50%;在子元素的左侧添加了一段距离,这段距离是父元素宽度的50%,接着因为translateX(50%) 设置百分比时的参照物是自身宽度,所以向左偏移了自身宽度的50%,就居中啦 ╮(‵▽′)╭

动动小手看看栗子

方法三:inline-block + text-align

主要代码:

  .parent { text-align: center; }
.child { display: inline-block; }

这种方法有一个问题是: parent设置了 text-align: center;后, 因为这个属性可继承,会导致 child中的文字也会居中,而这个效果是我们未必需要的,所以我们很多时候需要在 .child中加一句 text-align: left;

自己看看栗子

方法四:table + margin

主要代码:

  .child { display: table; margin: 0 auto; }

table的特点:宽度为内容宽度 的 块状元素,所以也可以用 margin: 0 auto;居中。

优点:只设置子元素样式就可以了,不需关心父元素。

看看栗子

不喜欢这第四个方案,table是辣么有语义的一个样式,为什么随便把人家变成table ( ̄. ̄)

2.垂直居中

父元素和子元素高度未知。

意欲达到的效果:

方法一:flex+ align-items

  .parent {
  display: flex;
  align-items: center;
}

水平居中的方法一

栗子

方法二:absolute + transform

  .parent { position: relative; }
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

水平居中的方法二

栗子

方法三:table-cell + vertical-align

  .parent {
  display: table-cell;
  vertical-align: middle;
}

vertical-align 可以作用在 inline元素, inline-table元素,以及 table-cell元素上。

栗子

3.水平垂直居中

父元素和子元素宽高都未知。

方法一:flex + justify-content + align-items

  .parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

综合了 水平居中垂直居中的方法一

栗子

方法二: absolute + transform

  .parent { position: relative; }
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

综合了 水平居中垂直居中的方法二

栗子

方法三:[inline-block + text-align] + [table-cell + vertical-align]

  .parent {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}
.child {
  display: inline-block;
}

栗子

多列布局

1.一列定宽 + 一列自适应

  <div class="parent">
  <div class="left"><p>left</p></div>
  <div class="right">
    <p>right</p>
    <p>right</p>
  </div>
</div>

方法1:float + margin

  .left {float: left; width: 100px;}
.right { margin-left: 120px;} //有20px是间距

方法2:(对方法一的改进)float + margin + (fix)

因为方法1在低版本浏览器有兼容性问题,所以改进一下。

  // 首先在right外面加了right-fix这个div
<div class="parent">
  <div class="left"><p>left</p></div>
  <div class="right-fix"> 
    <div class="right">
      <p>right</p>
      <p>right</p>
    </div>
  </div>
</div>

CSS改动:

STEP1:

  // .left 和 .right 设置暂时不变
.right-fix {float: right; width: 100%;}

效果为:(注意:我们把right-fix设置为白色背景,只是为了方便观察。)

STEP2:

可以看到,由于right-fix宽度为100%,所以跑到了left下面一行。想要回到同一行,需要给right-fix设置一个负的margin-left值-100px。

  .right-fix { margin-left: -100px; }

关于为什么设置了 margin-left: 100px;就可以使得回到同一行呢?是因为设置了负的margin-left值之后,浏览器计算right-fix元素的宽度后,会加上-100px,也就是减掉100px,这也就是left的宽度,所以left 与 right-fix 加起来没有超过整行的宽度。
想要进一步了解负的margin值可以参考这篇文章: CSS布局奇淫巧计之-强大的负边距

效果如图:

STEP3:

不幸的是,因为html文档中right-fix处于left后面,所以left被right-fix遮住了,实际应用中right-fix虽然没有背景色,但是我们还是不会希望它覆盖在left上面。

所以,我们需要提高 left 的层级。如何提高呢?由于设置了position: relative;的元素层级要高于普通元素,所以加上这样一条:

  .left{ position: relative; }

具体可以参考张鑫旭写的一篇讲解 position:relative;很详细的文章: CSS 相对/绝对(relative/absolute)定位系列(四)

最终达到我们要的效果:

到jsfiddle中自己试试去

方法3:float + overflow

  .left{
  width: 100px;
  margin-right: 20px;
}
.right {
  overflow: hidden;
}

原理是:设置了overflow:hidden; 之后,会触发BFC模式,而BFC模式内部的布局不受外部影响,所以不会受浮动影响,不会围绕left而是跑到left右边去了。

方法4:table

  .parent{
  display: table;
  width: 100%;
  table-layout: fixed; //加速table渲染,实现了布局优先
}
.left, .right {
  display: table-cell;
}
.left {
  width: 100px;
  padding-right: 20px;//因为table-cell不能设margin,所以设置padding来加间距
}

根据table的特性,left设置了100px后,right就占了剩余宽度。

方法5:flex

  .parent{ display: flex; }
.left{ width: 100px; margin-right: 20px; }
.right{ flex: 1; }

So easy.

2.多列定宽 + 一列自适应

再加一列定宽就行啦 o(≧v≦)o

3.不定宽 + 一列自适应

不定宽意思是:
1.可以随意更改宽度:比如改为100px,200px,同时不需要更改其他样式也可以做到两列自适应布局。
2.或不设置宽度而是由里面子元素的宽度决定。

以下方法对应 [一列定宽+一列自适应] 中的方法

方法1: float + margin ?

不好意思,做不到。

方法2: float + margin +(fix) ?

不好意思,也做不到。

方法3: float + overflow ?

阔以! right的样式没有依赖于width的宽度。代码量也少,很棒棒哦!

方法4:table

阔以! right的样式没有依赖于width的宽度,即不关心width的宽度。

方法5:flex

强大的flex当然可以~(傲娇脸 )

4.两列不定宽 + 一列自适应

没错,跟你想的一样,加一列不定宽的就行了,样式都一样 ㄟ( ▔, ▔ )ㄏ

5.等分布局

C + G = 4*(W + G)
以下例子假设间距G = 20px

结构:

  <div class="parent">
  <div class="column"><p>1</p></div>
  <div class="column"><p>2</p></div>
  <div class="column"><p>3</p></div>
  <div class="column"><p>4</p></div>
</div>

方法1:float

  .parent{ margin-left: -20px; }//就是上面公式中等号左边的G
.column{
  float: left;
  width: 25%;
  padding-left: 20px;//这里要注意,因为我们用padding来表示间距,所以如果你是给p元素设置了background-color,会发现没有间距,p标签的width才是上图中的W
  box-sizing: border-box;
}

方法2:table

  <div class="parent-fix">
    <div class="parent">
      <div class="column"><p>1</p></div>
      <div class="column"><p>2</p></div>
      <div class="column"><p>3</p></div>
      <div class="column"><p>4</p></div>
    </div>
</div>
  .parent-fix{
  margin-left: -20px;
}
.parent {
  display: table;
  width: 100%;
}
.column {
  display: table-cell;
  padding-left: 20px;//因为单元格不能设置margin,所以间距只能用padding来做。
}

因为table的width默认是随内容宽度变化的,所以需要手动设置 width: 100%;。又因为明确设置了宽度的元素就没办法用将margin设为负值的方式增加20px宽度了,所以需要在外面加一个父元素 parent-fix
这里大家可以自己试试比较一下给 parent-fix 设置width为100%不设置width时parent-fix实际宽度(用调试工具里的查看元素看)的区别来理解。

呐,jsfiddle示例在这

方法3:flex

  .parent { display: flex; }
.column { flex: 1; } 
.column + .column { margin-left: 20px; }//好用的兄弟选择器 (。・`ω´・)

上面这个等分布局这个整理完在另一篇CSS布局的文章里面给个链接

6.一列定宽+一列自适应(当其中较高的一列高度变化,另一列同步变化)

右侧变高,左侧高度随之变化:

↓↓

方法1:table

table的列之间有天然等高的特性。

就是上面 1.一列定宽 + 一列自适应中的 方法4:table

方法2:flex

flex也是天然的等高 <( ̄︶ ̄)> 因为它默认的align-items为stretch,即在交叉轴上默认拉伸占满整个容器。

仍旧是上面 1.一列定宽 + 一列自适应中的 方法5:flex

简单到不好意思给栗子

方法3:float

仍旧是参照上面 1.一列定宽 + 一列自适应中的 方法3:float + overflow,float并没有天然等高,所以要在这个基础上做改动。

  .left{
  width: 100px;
  margin-right: 20px;
}
.right {
  overflow: hidden;
}
//增加部分
.left, .right{
  padding-bottom: 9999px;//使得有背景色的部分变的很高
  margin-bottom: -9999px;//用负的margin抵消掉很高的padding,让高度变回left和right中较高的那部分的内容高度,以便parent用overflow: hidden;去隐藏掉超出部分
}
.parent {
  overflow: hidden;//隐藏掉超出边界的部分 
}

其实left的实际高度并没有变,是一种伪等高,只是背景变高。

栗子

7.全等四宫格

这是练习题,置几试试吧。

  <div class="parent">
  <div class="outer">
    <div class="column>1</div>
    <div class="column>2</div>
  </div>
  <div class="outer">
    <div class="column>3</div>
    <div class="column>4</div>
  </div>
</div>

方法1:flex

  .parent {
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
}
.outer {
  flex-basis: 100%;
  display: flex;
  justify-content: space-between;
}

一颗仅供参考的栗子

方法2:float

我的栗子

方法3:table

一个栗子不一定对

全屏布局

1.定宽(px)+自适应

只有主内容区 right 随内容滚动。

方法1.position

  <div class="parent">
<div class="top">top</div>
<div class="left">left</div>
<div class="right"><div class="help-right">right</div></div>
<div class="bottom">bottom</div>
</div>
  html, body, .parent {height: 100%; overflow: hidden;}//为了让整个页面不滚动
.top {
  position: absolute;
  top: 0; 
  left: 0; right: 0; //注意这个很棒的设置!可以自动占满整行 ヾ(o◕∀◕)ノ 
  height: 100px;
}
.left {
  position: absolute;
  left: 0;
  top: 100px; bottom: 50px;
  width:200px;
}
.right {
  position: absolute;
  left: 200px; right: 0;
  top: 100px; bottom: 50px; //这也是上下占满除了top和bottom之外的所有高度
  overflow: auto;//让主内容区可以滚动
}
.help-right {//假装有很多内容
  width: 1000px;
  height: 1000px;
}
.bottom{
  position: absolute;
  bottom: 0; 
  left: 0; right: 0;
  height: 50px;
}

动手写写才记得住

方法2.flex

  <div class="parent">
<div class="top">top</div>
<div class="middle">
<div class="left">left</div>
<div class="right"><div class="help-right">right</div></div>
</div>
<div class="bottom">bottom</div>
</div>
  html, body, .parent {height: 100%; overflow: hidden;}
.parent {display: flex; flex-direction: column;}
.top { height: 100px; }
.middle {flex: 1; display: flex;}
.left { width:200px; }
.right { flex: 1; overflow: auto; }
.help-right { width: 1000px; height: 1000px; }
.bottom{ height: 50px; }

栗子

2.百分比定宽(%)+自适应

方法1.position , 方法2.flex :

把原来的用px写的定宽改成百分比就可以了。是相对于body的高度和宽度来变化的。感觉top和bottom高度设置百分比不是很实用。

3.自适应+自适应

方法1.position

定宽的高度和宽度影响旁边栏的布局,所以实现不了 - 。-

方法2.flex

阔以实现,而且相当简单 ╮(╯▽╰)╭ 把刚刚设置了高度和宽度的地方去掉就可以了 ∑(っ °Д °;)っ

惊人的栗子

方法3.Grid

阔以实现,但是因为还是W3C的草案,所以会经常变化,不稳定,而且浏览器支持也不好。

响应式

想要达到的效果

只写一个网站,在多个终端显示,在小屏幕上会隐藏部分元素。

现在的情况

在PC端浏览器中可以正常访问的网站,到了手机上之后,内容就会变得特别小。
原因:所有的移动设备都有一个viewport(视窗),这个视窗不是手机屏幕大小,而是一个虚拟的窗口,比如iPhone4的viewport宽度为980px(如下图所示)。显示的时候再按照比例将这980px的内容压缩显示到实际的屏幕宽度中。

所以为防止让页面缩小,在移动设备中,我们会做如下设置

  <meta name="viewport" content="
 width=device-width //让宽度等于设备宽度,因为不同的移动设备宽度不同 iphone4为320px
 ,initial-scale=1.0 //初始缩放1.0, 即不缩放,网站就不会被缩小了
 ,user-scalable=no //防止用户手动缩放
">

设置结束之后,如何具体开发?

方法1.宽度尽量自适应,而不要用定宽。

方法2.用媒体查询 @media

  @media screen and (max-width: 320px) {
  //最大宽度为320px,即视窗宽度小于等于320px
  div{..}
  .class-name{...}
}

@media screen and (min-width: 320px) and (max-width: 769px){
  //最小宽度为320px,最大宽度为769px,即视窗宽度大于320px,小于769px
}

响应式

目的

减少卡顿
利于SEO
便于代码维护

方法

1. 减少页面请求

减少css文件请求

(1)多个css文件合并成一个
(2)少量css样式内联
(3)避免用import的方式引入css文件,因为每个import语句都会产生一个css请求,并且是同步的请求。

2.减少资源文件大小

(1)减少图片大小
选择合适的图片格式,小尺寸、半透明的用png,大尺寸、色彩绚丽用jpg(因为jpg会对图片进行压缩)
压缩图片

(2)css值缩写
margin,padding,border,font,border-radius等属性

(3)省略值为0 的单位

  margin: 0 10px;
line-height: .5;
background-position: 50% 0;

(4)颜色值最短表示

  red
rgb(0,0,0)
rgba(0,0,0,0)
#000000
#000

(5)css选择器合并

  .left, .right {...}

(6)文件压缩
用工具对文件进行自动压缩,去掉空格。

3.提升页面性能

加载顺序

css通常放在head中,而js通常放在body底部,因为js会阻碍其他资源加载。

减少标签数量。

选择器长度

  body .menu ul li a { ... } //太长了
.menu a { ... } //更好

避免耗性能属性

比如:

  expression
filter
border-radius
box-shadow
gradients

给图片设置固定宽高,并且图片实际宽高与设置宽高相同,否则浏览器会回流设置多次宽高

所有表现用css实现

4.通过规范提高代码可读性,可维护性

(1)规范:缩进,变量名等
(2)语义化:除了标签,css、id名最好也尽量有意义
(3)尽量避免Hack,一定要用也要统一的标识,比如IE7用*
(4)模块化:相关联的结构做成一个个模块,复用性更强
(5)添加注释

规范与模块化

规范

1.注释的文字两侧需加空格,防止因编码问题导致注释失效

2.为避免命名污染,可以给class加前缀,比如:

  g- 布局命名
m- 模块命名

3.语义化命名

  //结构化命名
top { ... }

//改用语义化命名
nav { ... }

4.属性的书写顺序

模块化

什么是模块化

  1. 一系列相关联的结构组成的整体

  2. 带有一定的语义,而非表现

比如,翻页器(或叫分页器paging)、轮播图。

怎么做?

  1. 为模块分类命名(如.m-, .md-)

  2. 以一个主选择器开头(模块根节点)

  3. 使用以主选择器开头的后代选择器(模块子节点)

  <div class="m-nav">
  <ul>
    <li class="z-crt"><a>链接</a></li>
    <li><a>链接</a></li>
  </ul>
</div>
  //根节点
.m-nav { ... }
//子节点
.m-nav ul{ ... }
.m-nav li{ ... }
.m-nav a{ ... }
.m-nav .z-crt a{ ... }/* 交互状态变化 */

若有一个模块只是比上述模块多了一个按钮,其余部分完全相同,怎么办?

怎样扩展?

为根节点加一个class就好了,这里我们加一个 m-nav-1

  <div class="m-nav m-nav-1">
  <ul>
    <li class="z-crt"><a>链接</a></li>
    <li><a>链接</a></li>
  </ul>
  <a class="btn">我是新加的a标签</a>
</div>
  //变化的部分在 .m-nav-1 这个新class中写
.m-nav-1 { ... }
.m-nav-1 a{ ... }
.m-nav-1 .btn{ ... }

网易的规范和代码库

规范页:包含了CSS规范、HTML规范和工程师规范

代码库:包含了常用的布局方式、常见模块和元件的实现以及一些bug、技巧等

——————
教是最好的学。

你可能感兴趣的:(html,css,html5,css3,页面布局)