CSS 能不能 检测(怎么说都行)到 滚轮的事件

html-css028

CSS 能不能 检测(怎么说都行)到 滚轮的事件,第1张

2015年3月26日,W3C的CSS工作组发布了CSS滚动界限点模块(CSS Scroll Snap Points Level 1)的首份工作草案(First Public Working Draft)。在浏览可以连续上下滚动或左右滚动的连续页面或一组图片时,通过触摸屏的触摸滑动或鼠标滚轴的滚动操作可以获得较好用户体验。但无论是触屏滑动还是鼠标滚轴都不容易精确的控制操作所产生的滚动量输入(imprecise nature of scrolling inputs),对于Web开发者来说,需要更好的控制滚动体验,并创建更丰富的页面内容呈现效果。 该模块提供了一组新特性,通过定义滚动范围的界限点(snap points)用来控制触屏滑动(panning)及滚动行为。

由神秘到简单 教你在网页中添加微软地图

作者:站长收集教程来源:网络点击数:2更新时间:2005-12-17

自Google推出地图服务以后,微软和百渡也相继推出地图服务。地图成为目下网络流行的时尚,如果你想追赶它,那么来吧,我将会帮助你学会使用微软的Virtual Earth Map Control,为你的网站添加一道亮丽的风景。

本文最终效果图:

MapControl控件

Virtual Earth Map Control脚本可以在MSN网站下载:http://virtualearth.msn.com/js/MapControl.js。

当然你可以直接在网站中链接这个脚本,但这会导致一些安全上的问题,因为缺省情况下大部分的浏览器不会允许来自其他的不是当前正在浏览的站点的JavaScript程序运行。使用者必须确认他们允许来自VirtualEarth的脚本运行,这样会给用户不爽的感觉。

简单的方式就是下载MapControl.js文件到你的站点,这样就可以轻松访问并进行编程了。

创建Map Control实例

为了创建一个Map Control实例,你需要在你的页面里写一个小方法。这将会创建一个MapControl的实例,在页面上放置它,并设置control里初始显示的内容。

VE_MapControl的构造函数原型如下:

VE_MapControl(Latitude, Longitude, Zoom, MapStyle, PositionType, Left, Top, Width, Height)

Latitude:在control里显示的地图中心的纬度;

Longitude:在control里显示的地图中心的经度;

Zoom:显示地图的缩放尺度。可以设置为2到18的数。2是允许的最远的俯瞰距离,18是允许的最近的俯瞰距离。

MapStyle:显示地图的风格。目前有3种式样可选:高空的(aerial),道路的(road)和混合的(hybrid)。用每种式样的首字母小写来代表该式样。

·a-aerial:显示高空的卫星图像。

·r-road:显示地区的街道地图;

·h-hybrid:显示以上两者的结合,卫星图像将和道路和位置信息重叠在一起。

PositionType:control在页面上的放置的方式,可选项为相对(relative)和绝对(absolute)。

Left:control左边在页面上的位置。

Top:control上部在页面上的位置。

Width:control宽度。

Height:control高度。

例子:

map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 400, 10, 400, 300)

一个简单的具有Virtual Earth map control的页面可以如下创建:

<html>

<head>

<title>My Virtual Earth</title>

<script src="MapControl.js"></script>

<script>

var map = null

function OnPageLoad()

{

map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500)

document.body.appendChild(map.element)

map.onEndContinuousPan = function(e)

{

document.getElementById("info").innerHTML =

’Latitude = ’ + e.latitude +

’, Longitude = ’ + e.longitude +

’, Zoom=’ + e.zoomLevel

}

}

</script>

</head>

<body onLoad="OnPageLoad()">

<div id="info" style="font-size:10pt">

</div>

</body>

</html>

效果图如下所示,你可以使用一些control的特性:

·拖动整个地图刷新显示

·使用鼠标滚轮进行缩放

·双击某个地点进行放大

从Map Control接收事件

当control上显示的地图变化的时候,map control会触发事件,事件提供了有关地图的相关信息。

你可以从control上获取的事件有:

· onStartContinuousPan

· onEndContinuousPan

· onStartZoom

· onEndZoom

· onMouseClick

· onMouseDown

· onMouseUp

所有的事件函数都传入一个参数。事件参数在MapControl.js这样被定义:

function VE_MapEvent(srcMapControl,latitude,longitude,zoomLevel)

{

this.srcMapControl=srcMapControl

this.latitude=latitude

this.longitude=longitude

this.zoomLevel=zoomLevel

}

纬度(latitude)和经度(longitude)表明了地图的中心位置。缩放尺度(zoomlevel)提供了可以缩放的尺度的量。

我们首先看到的是第一个event--载入事件(panning event)。每次地图开始或者停止载入或者卷动(scrolling)时都会触发此事件。当地图开始卷动时onStartContinousPan事件会触发,当map control停止卷动地图时onEndContinousPan事件会被触发。

我们可以给上一步中创建的简单页面增加一些代码,来处理onEndContinuousPan事件,显示当前map的中心信息。

代码如下:

<html>

<head>

<title>My Virtual Earth</title>

<script src="MapControl.js"></script>

<script>

var map = null

function OnPageLoad()

{

map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500)

document.body.appendChild(map.element)

map.onEndContinuousPan = function(e)

{

document.getElementById("info").innerHTML =’Latitude = ’ + e.latitude +

’, Longitude = ’ + e.longitude +

’, Zoom=’ + e.zoomLevel

}

}

</script>

</head>

<body onLoad="OnPageLoad()">

<div id="info" style="font-size:10pt">

</div>

</body>

</html>

我们可以通过增加一个函数处理onEndZoom事件完成以上功能:

<html>

<head>

<title>My Virtual Earth</title>

<script src="MapControl.js"></script>

<script>

var map = null

function OnPageLoad()

{

map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500)

document.body.appendChild(map.element)

var updateInfo = function(e)

{

document.getElementById("info").innerHTML =’Latitude = ’ + e.latitude +’, Longitude = ’ + e.longitude +

’, Zoom=’ + e.zoomLevel

}

map.onEndContinuousPan = updateInfo

map.onEndZoom = updateInfo

}

</script>

</head>

<body onLoad="OnPageLoad()">

<div id="info" style="font-size:10pt">

</div>

</body>

</html>

地图显示如下:

变换地图样式

上面我们已经介绍了有三种样式可以选择:

·a-aerial:显示高空的卫星图像。

·r-road:显示地区的街道地图;

·h-hybrid:显示以上两者的结合,卫星图像将和道路和位置信息重叠在一起。

当map control显示的时候,可以通过SetMapStyle函数来变换地图样式:

SetMapStyle(mapStyle)

函数通过mapStyle参数来设置式样,如上文所述,使用a,r或者h。

我们可以通过增加两个checkbox来允许用户改变地图样式:

<html>

<head>

<title>My Virtual Earth</title>

<script src="MapControl.js"></script>

<script>

var map = null

function OnPageLoad()

{

map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500)

document.body.appendChild(map.element)

var updateInfo = function(e)

{

document.getElementById("info").innerHTML = ’Latitude = ’ + e.latitude + ’, Longitude = ’ + e.longitude +

’, Zoom=’ + e.zoomLevel

}

map.onEndContinuousPan = updateInfo

map.onEndZoom = updateInfo

}

function ChangeMapStyle()

{

var Aerial = document.getElementById("AerialStyleCheck")

var Vector = document.getElementById("VectorStyleCheck")

var s = ’r’

if (Aerial.checked &&Vector.checked)

{

s = ’h’

}

else if (Aerial.checked)

{

s = ’a’

}

map.SetMapStyle(s)

}

</script>

</head>

<body onLoad="OnPageLoad()">

<div id="info" style="font-size:10pt">

</div>

<div id="MapStyle" style="POSITION:absoluteLEFT:470pxTOP:60px">

<input id="VectorStyleCheck" type="checkbox" onclick="ChangeMapStyle()" checked="checked">

Street Style

<input id="AerialStyleCheck" type="checkbox" onclick="ChangeMapStyle()">

Aerial Style

</div>

</body>

</html>

效果如下:

给地图增加图钉(pin)标记

增加图钉标记的功能允许我们在map control上指出特殊位置。图钉在map control上显示覆盖的信息。AddPushpin方法的原型如下:

AddPushpin(id,lat,lon,width,height,className,innerHtml)

id:图钉的标识符。在map control上每个图钉都具有唯一的标识号。

lat:放置图钉的地点的纬度。

lon:放置图钉的地点的经度。

width:图钉的宽度。

height:图钉的高度。

width和height使用来计算图钉的偏移,使得图钉可以放置到指定的经纬度。

提示:如果你希望使得图钉的底部右脚处于指定的经纬度,你需要将这些值乘2:

Classname:图钉的样式类型(style class)的名称。如果没有这个参数图钉不会显示。样式可以通过CSS文件描述或者通过嵌入式的代码描述。

innerHTML:显示在图钉上的文字。

下面的例子中,使用onMouseClick事件,当用户点击的时候给点击处增加一个图钉:

<html>

<head>

<title>My Virtual Earth</title>

<style type="text/css" media=screen>

<!--

.pin

{

width:44pxheight:17px

font-family:Arial,sans-serif

font-weight:boldfont-size:8pt

color:Whiteoverflow:hidden

cursor:pointertext-decoration:none

text-align:centerbackground:#0000FF

border:1px solid #FF0000

z-index:5

}

-->

</style>

<script src="MapControl.js"></script>

<script>

var map = null

function OnPageLoad()

{

map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500)

document.body.appendChild(map.element)

var updateInfo = function(e)

{

document.getElementById("info").innerHTML = ’Latitude = ’ + e.latitude + ’, Longitude = ’ + e.longitude +

’, Zoom=’ + e.zoomLevel

}

map.onEndContinuousPan = updateInfo

map.onEndZoom = updateInfo

map.onMouseClick = function(e)

{

map.AddPushpin(’pin’, e.latitude, e.longitude, 88, 34, ’pin’, ’MyPin’)

}

}

function ChangeMapStyle()

{

var Aerial = document.getElementById("AerialStyleCheck")

var Vector = document.getElementById("VectorStyleCheck")

var s = ’r’

if (Aerial.checked &&Vector.checked)

{

s = ’h’

}

else if (Aerial.checked)

{

s = ’a’

}

map.SetMapStyle(s)

}

</script>

</head>

<body onLoad="OnPageLoad()">

<div id="info" style="font-size:10pt">

</div>

<div id="MapStyle" style="POSITION:absoluteLEFT:470pxTOP:60px">

<input id="VectorStyleCheck" type="checkbox" onclick="ChangeMapStyle()" checked="checked">

Street Style

<input id="AerialStyleCheck" type="checkbox" onclick="ChangeMapStyle()">

Aerial Style

</div>

</body>

</html>

这样会导致一些问题:

·每次地图被拖动时,另外一个图钉被增加。

·双击地图进行放大的功能无法完成,因为每次接收到双击事件,图钉首先会被增加。

·单个标识符可以增加多个图钉。

一个解决方案是对onMouseClick事件进行特殊处理,我们可以每次增加一个图钉的时候移除以前的图钉。

使用RemovePushpin函数移去一个图钉:

RemovePushpin(id)

这个函数通过传入的id标识符来去除某个图钉。

去除一个图钉也会同时移去所有相同标识符的图钉。

上文中的代码可以修改以移去以前所有的图钉:

map.onMouseClick = function(e){

map.RemovePushpin(’pin’)

map.AddPushpin(’pin’, e.latitude, e.longitude, 88, 34, ’pin’, ’MyPin’)

}

这样就只有一个图钉来标明上次点击的位置:

增加导航Control

map control有一些内在的导航特性,但是有些时候需要提供一些额外的control在web页面上来允许用户来控制地图的导航。下面我们介绍如何在web页面上增加按钮来控制地图的显示。

载入

我们首先为地图的移动增加按钮。在HTML的Body元素中可以增加一些简单的HTML代码:

<input type="button" value="Pan Up" onclick="DoPanUp()" style="position:absoluteleft:60pxtop:600px"/>

<input type="button" value="Pan Left" onclick="DoPanLeft()" style="position:absoluteleft:10pxtop:630px"/>

<input type="button" value="Pan Right" onclick="DoPanRight()" style="position:absoluteleft:100pxtop:630px"/>

<input type="button" value="Pan Down" onclick="DoPanDown()" style="position:absoluteleft:45pxtop:660px"/>

下面增加对点击按钮的事件进行处理的脚本段。使用PanMap方法。它可以接受2个参数,x和y。它们指出了在x和y方向上可以移动多少位置。

function DoPanUp()

{

map.PanMap(0, -100)

}

function DoPanDown()

{

map.PanMap(0, 100)

}

function DoPanLeft()

{

map.PanMap(-100, 0)

}

function DoPanRight()

{

map.PanMap(100, 0)

}

如果你在浏览器里进行浏览,并且点击按钮,你会发现地图在一次次的跳跃。这样的用户体验可不好。最好是使得地图在各个方向上慢慢的平滑卷动。可以使用ContinuousPan函数来控制。除了x和y之外,它还接受一个参数,这个参数指定了进行平滑卷动的次数。这样可以指定多次的移动来提供地图平滑卷动的效果。

function DoPanUp()

{

map.ContinuousPan(0, -10, 20)

}

function DoPanDown()

{

map.ContinuousPan(0, 10, 20)

}

function DoPanLeft()

{

map.ContinuousPan(-10, 0, 20)

}

function DoPanRight()

{

map.ContinuousPan(10, 0, 20)

}

缩放

下面增加两个按钮用于缩放:

<input type="button" value="Zoom In" onclick="DoZoomIn()" style="position:absoluteleft:250pxtop:630px"/>

<input type="button" value="Zoom Out" onclick="DoZoomOut()" style="position:absoluteleft:340pxtop:630px"/>

下面的代码实现ZoomIn和ZoomOut函数,每个函数给缩放尺度增或者减1。

function DoZoomIn() { map.ZoomIn()}function DoZoomOut() { map.ZoomOut()}

如果你按照上面所说进行编程,那么你的页面和文中开始的图是基本类似的。完整代码如下:

<html>

<head>

<title>My Virtual Earth</title>

<style type="text/css" media=screen>

<!--

.pin

{

width:44pxheight:17px

font-family:Arial,sans-serif

font-weight:boldfont-size:8pt

color:Whiteoverflow:hidden

cursor:pointertext-decoration:none

text-align:centerbackground:#0000FF

border:1px solid #FF0000

z-index:5

}

-->

</style>

<script src="MapControl.js"></script>

<script>

var map = null

function OnPageLoad()

{

map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500)

document.body.appendChild(map.element)

var updateInfo = function(e)

{

document.getElementById("info").innerHTML =

’Latitude = ’ + e.latitude +

’, Longitude = ’ + e.longitude +

’, Zoom=’ + e.zoomLevel

}

map.onEndContinuousPan = updateInfo

map.onEndZoom = updateInfo

map.onMouseClick = function(e)

{

map.RemovePushpin(’pin’)

map.AddPushpin(’pin’, e.latitude, e.longitude, 88, 34, ’pin’, ’MyPin’)

}

}

function ChangeMapStyle()

{

var Aerial = document.getElementById("AerialStyleCheck")

var Vector = document.getElementById("VectorStyleCheck")

var s = ’r’

if (Aerial.checked &&Vector.checked)

{

s = ’h’

}

else if (Aerial.checked)

{

s = ’a’

}

map.SetMapStyle(s)

}

function DoPanUp() { map.ContinuousPan(0, -10, 20)}

function DoPanDown() { map.ContinuousPan(0, 10, 20)}

function DoPanLeft() { map.ContinuousPan(-10, 0, 20)}

function DoPanRight() { map.ContinuousPan(10, 0, 20)}

function DoZoomIn() { map.ZoomIn()}

function DoZoomOut() { map.ZoomOut()}

</script>

</head>

<body onLoad="OnPageLoad()">

<div id="info" style="font-size:10pt">

</div>

<div id="MapStyle" style="POSITION:absoluteLEFT:470pxTOP:60px">

<input id="VectorStyleCheck" type="checkbox" onclick="ChangeMapStyle()" checked="checked">

Street Style

<input id="AerialStyleCheck" type="checkbox" onclick="ChangeMapStyle()">

Aerial Style

</div>

<input type="button" value="Pan Up" onclick="DoPanUp()" style="position:absoluteleft:60pxtop:600px"/>

<input type="button" value="Pan Left" onclick="DoPanLeft()" style="position:absoluteleft:10pxtop:630px"/>

<input type="button" value="Pan Right" onclick="DoPanRight()" style="position:absoluteleft:100pxtop:630px"/>

<input type="button" value="Pan Down" onclick="DoPanDown()" style="position:absoluteleft:45pxtop:660px"/>

<input type="button" value="Zoom In" onclick="DoZoomIn()" style="position:absoluteleft:250pxtop:630px"/>

<input type="button" value="Zoom Out" onclick="DoZoomOut()" style="position:absoluteleft:340pxtop:630px"/>

</body>

</html>

设置其他control的脚本

本文一开始我就提到可以从http://virtualearth.msn.com/js/MapControl.js页面找到我们所需要的Virtual Earth Map Control,这里我们同样需要另外一个包含其他control的脚本文件,这个文件可以在http://virtualearth.msn.com/js/ve.js下载到。

同样如果你需要在你自己的站点使用这个脚本,你必须将这个脚本文件拷贝到你自己的站点。如果你从VirtualEarth站点直接使用这个脚本,用户将会收到安全警告,也可能会根本都看不见这个control。

你必须引进这个脚本:

<script src="/ViaVirtualEarth/Portals/0/VE.js"></script>

这里要说明的是其他的窗口部件假设你的页面上的map control是命名地图。

罗盘控制

第一个我们将要增加的是罗盘control。它提供了在地图上进行漫游的各种方式。它是通过一个图像代表的,最后使用一个透明的gif图像以免其覆盖所需要的地图。你可以自己创建或者使用本例中的图片。

在OnPageLoad方法里你可以通过创建一个文档元素VE_Compass并设置它的元素属性来创建和摆放罗盘control。

最好的方式就是将其单独作为一个方法,从OnPageLoad方法里进行调用。

function CreateCompass()

{

var el=document.createElement("div")

el.id="VE_Compass"

el.style.background="url(images/compass.gif)"

el.onmousedown=VE_Compass._MouseDown

el.onmouseup=VE_Compass._MouseUp

el.onmousemove=VE_Compass._MouseMove

el.style.position="absolute"

el.style.top = 100

el.style.left = 15

el.style.zIndex=31

el.style.width = 93

el.style.height = 91

VE_Compass.element=el

document.body.appendChild(el)

}

function OnPageLoad(){ CreateCompass()...

页面此时会显示一个罗盘在地图左上角,你可以用它来漫游整个地图。

地图比例尺组件

地图比例尺组件提供了对地图显示的比例的调整功能,这在估算距离的时候比较有用。组件是由2行的一个表格来表示的。在代码里必须正确的定义表格和行的名称,这些名称可以被其他的VE.js文件中的代码使用以在地图变化的时候更新比例尺

首先在HTML中增加一个表格:

<table id="VE_MapScale" cellpadding="0" cellspacing="0" unselectable="on">

<tr>

<td>

<div id="VE_MapScaleLabel" unselectable="on"> </div>

</td>

</tr>

<tr>

<td>

<div id="VE_MapScaleBar" unselectable="on"> </div>

</td>

</tr>

</table>

然后增加一些样式来定义最终的比例尺的显示:

#VE_MapScale

{

position: absolute

width: 150px

height: 18px

padding: 0

margin: 0

z-index: 31

}

#VE_MapScaleLabel

{

height: 22px

font-family: Verdana

font-size: 12pt

color: black

overflow: hidden

}

#VE_MapScaleBar

{

width: 150px

height: 5px

background: green

overflow: hidden

}

增加如下的代码在OnPageLoad方法里,以在地图上摆放比例尺,并且显示初始的比例大小:

PositionElement(document.getElementById("VE_MapScale"), 300, 550, 150, 18)

UpdateMapScale()

最后当每次缩放的时候,比例尺都会需要被更新。在OnPageLoad函数中,我们增加对此事件进行处理的代码。我们需要增加一个对更新比例尺的调用。

map.onEndZoom=function(e){ document.getElementById("info").innerHTML = ’Latitude = ’ + e.latitude + ’, Longitude = ’ + e.longitude+’), Zoom=’ + e.zoomLevelUpdateMapScale()}

缩放控制

缩放control提供了一个灵活的用户接口,用来控制地图的缩放。它还提供了可视化的回馈,用来提供地图可以缩放的量以及当前的比例信息。

首先我们需要增加一些样式表来描述control的样子,它主要包含4个部分:主体条,滑动杆,左边的缩小控制和右边的放大控制。每个部分都需要一个图片文件来定义如何显示这些控制部分。

在这里我创建了简单的图片,你也可以拷贝过去使用。缩放的样式定义应该和下面的类似:

.VE_ZoomControl_minus

{

position: absolute

width: 26px

height: 32px

background: url(images/ZoomOut.gif)

display: inline

text-align: center

text-decoration: none

color: black

}

.VE_ZoomControl_plus

{

position: absolute

width: 26px

height: 32px

background: url(images/ZoomIn.gif)

display: inline

text-align: center

text-decoration: none

color: black

}

.VE_ZoomControl_bar

{

position: absolute

width: 128px

height: 32px

background: url(images/ZoomBar.gif)

display: inline

}

.VE_ZoomControl_slider

{

position: absolute

width: 8px

height: 24px

background: url(images/ZoomSlider.gif)

overflow: hidden

display: inline

}

这些创建缩放控制的代码可以被放到OnPageLoad函数的最后,以在调入页面的同时初始化这些control。

var zm=VE_ZoomControl.Create(5, 550, 9, "absolute")

document.body.appendChild(zm)

为了让缩放控制反映出当前的缩放尺度,我们需要在每次缩放发生的时候调节它。所以在onEndZoom函数的最后增加对control的刷新:

map.onEndZoom=function(e)

{

document.getElementById("info").innerHTML = ’Latitude = ’ + e.latitude + ’, Longitude = ’ + e.longitude + ’), Zoom=’ + e.zoomLevelUpdateMapScale()

VE_ZoomControl.SetZoomLevel(map.GetZoomLevel())

}

下面我们看一看我们目前的页面是什么样子了,它已经增加了三个大的组件了,如下所示:

添加便笺条

和其他control一样,我们首先需要定义便笺条的样式,我们使用和Virtual Earth网站一样的样式:

.VE_Panel_el

{

overflow: hidden

z-index: 31

border: 1px solid #cbcbcb

padding: 0

margin: 0

background: white

}

.VE_Panel_title

{

position: abso

Ⅰ.绝对定位居中(Absolute Centering)技术

实现垂直居中仅需要声明元素高度和下面的CSS:

[css] view plaincopy

.Absolute-Center {

margin: auto

position: absolute

top: 0 left: 0 bottom: 0 right: 0

}

这只是非常常见的一种小技术,

优点:

1.支持跨浏览器,包括IE8-IE10.

2.无需其他特殊标记,CSS代码量少

3.支持百分比%属性值和min-/max-属性

4.只用这一个类可实现任何内容块居中

5.不论是否设置padding都可居中(在不使用box-sizing属性的前提下)

6.内容块可以被重绘。

7.完美支持图片居中。

缺点:

1.必须声明高度(查看可变高度Variable Height)。

2.建议设置overflow:auto来防止内容越界溢出。(查看溢出Overflow)。

3.在Windows Phone设备上不起作用。

浏览器兼容性:

Chrome,Firefox, Safari, Mobile Safari, IE8-10.

绝对定位方法在最新版的Chrome,Firefox, Safari, Mobile Safari, IE8-10.上均测试通过。

对比表格:

绝对居中法并不是唯一的实现方法,实现垂直居中还有些其他的方法,并各有各的优势。采用哪种技术取决于你的浏览器是否支持和你使用的语言标记。这个对照表有助于你根据自己的需求做出正确的选择。

解释:

通过以上描述,绝对居中(AbsoluteCentering)的工作机理可以阐述如下:

1、在普通内容流(normal content flow)中,margin:auto的效果等同于margin-top:0margin-bottom:0。

W3C中写道If 'margin-top', or'margin-bottom' are 'auto', their used value is 0.

2、position:absolute使绝对定位块跳出了内容流,内容流中的其余部分渲染时绝对定位部分不进行渲染。

Developer.mozilla.org:...an element that is positioned absolutely is taken out of the flow and thustakes up no space

3、为块区域设置top: 0left: 0bottom: 0right: 0将给浏览器重新分配一个边界框,此时该块block将填充其父元素的所有可用空间,父元素一般为body或者声明为position:relative的容器。

Developer.mozilla.org:For absolutely positioned elements, the top, right, bottom, and left propertiesspecify offsets from the edge of the element's containing block (what theelement is positioned relative to).

4、  给内容块设置一个高度height或宽度width,能够防止内容块占据所有的可用空间,促使浏览器根据新的边界框重新计算margin:auto

Developer.mozilla.org: The margin of the[absolutely positioned] element is then positioned inside these offsets.

5、由于内容块被绝对定位,脱离了正常的内容流,浏览器会给margin-top,margin-bottom相同的值,使元素块在先前定义的边界内居中。

W3.org: If none of the three [top, bottom,height] are 'auto': If both 'margin-top' and 'margin-bottom' are 'auto', solvethe equation under the extra constraint that the two margins get equal values.AKA: center the block vertically

这么看来, margin:auto似乎生来就是为绝对居中(Absolute Centering)设计的,所以绝对居中(Absolute Centering)应该都兼容符合标准的现代浏览器。

简而言之(TLDR):绝对定位元素不在普通内容流中渲染,因此margin:auto可以使内容在通过top: 0left: 0bottom: 0right: 0设置的边界内垂直居中。