-
Notifications
You must be signed in to change notification settings - Fork 16
/
db.json
1 lines (1 loc) · 361 KB
/
db.json
1
{"meta":{"version":1,"warehouse":"1.0.3"},"models":{"Asset":[{"_id":"source/CNAME","path":"CNAME","modified":1},{"_id":"source/image/boxes/inline-boxes.psd","path":"image/boxes/inline-boxes.psd","modified":1},{"_id":"source/image/boxes/inline-boxes.png","path":"image/boxes/inline-boxes.png","modified":1},{"_id":"source/image/boxes/block-boxes.psd","path":"image/boxes/block-boxes.psd","modified":1},{"_id":"source/image/boxes/block-boxes.png","path":"image/boxes/block-boxes.png","modified":1},{"_id":"source/image/boxes/anon-inline.psd","path":"image/boxes/anon-inline.psd","modified":1},{"_id":"source/image/boxes/anon-inline.png","path":"image/boxes/anon-inline.png","modified":1},{"_id":"source/image/adapter/iPhone.png","path":"image/adapter/iPhone.png","modified":1},{"_id":"themes/next/source/vendors/velocity/velocity.ui.min.js","path":"vendors/velocity/velocity.ui.min.js","modified":1},{"_id":"themes/next/source/vendors/velocity/velocity.ui.js","path":"vendors/velocity/velocity.ui.js","modified":1},{"_id":"themes/next/source/vendors/velocity/velocity.min.js","path":"vendors/velocity/velocity.min.js","modified":1},{"_id":"themes/next/source/vendors/velocity/velocity.js","path":"vendors/velocity/velocity.js","modified":1},{"_id":"themes/next/source/vendors/velocity/bower.json","path":"vendors/velocity/bower.json","modified":1},{"_id":"themes/next/source/vendors/jquery/index.js","path":"vendors/jquery/index.js","modified":1},{"_id":"themes/next/source/vendors/fastclick/lib/fastclick.min.js","path":"vendors/fastclick/lib/fastclick.min.js","modified":1},{"_id":"themes/next/source/vendors/fastclick/lib/fastclick.js","path":"vendors/fastclick/lib/fastclick.js","modified":1},{"_id":"themes/next/source/vendors/fastclick/bower.json","path":"vendors/fastclick/bower.json","modified":1},{"_id":"themes/next/source/vendors/fastclick/README.md","path":"vendors/fastclick/README.md","modified":1},{"_id":"themes/next/source/vendors/fastclick/LICENSE","path":"vendors/fastclick/LICENSE","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/jquery.fancybox.pack.js","path":"vendors/fancybox/source/jquery.fancybox.pack.js","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/jquery.fancybox.js","path":"vendors/fancybox/source/jquery.fancybox.js","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/jquery.fancybox.css","path":"vendors/fancybox/source/jquery.fancybox.css","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/helpers/jquery.fancybox-thumbs.js","path":"vendors/fancybox/source/helpers/jquery.fancybox-thumbs.js","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/helpers/jquery.fancybox-thumbs.css","path":"vendors/fancybox/source/helpers/jquery.fancybox-thumbs.css","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/helpers/jquery.fancybox-media.js","path":"vendors/fancybox/source/helpers/jquery.fancybox-media.js","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/helpers/jquery.fancybox-buttons.js","path":"vendors/fancybox/source/helpers/jquery.fancybox-buttons.js","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/helpers/jquery.fancybox-buttons.css","path":"vendors/fancybox/source/helpers/jquery.fancybox-buttons.css","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/helpers/fancybox_buttons.png","path":"vendors/fancybox/source/helpers/fancybox_buttons.png","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/[email protected]","path":"vendors/fancybox/source/[email protected]","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/fancybox_sprite.png","path":"vendors/fancybox/source/fancybox_sprite.png","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/fancybox_overlay.png","path":"vendors/fancybox/source/fancybox_overlay.png","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/[email protected]","path":"vendors/fancybox/source/[email protected]","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/fancybox_loading.gif","path":"vendors/fancybox/source/fancybox_loading.gif","modified":1},{"_id":"themes/next/source/vendors/fancybox/source/blank.gif","path":"vendors/fancybox/source/blank.gif","modified":1},{"_id":"themes/next/source/js/ua-parser.min.js","path":"js/ua-parser.min.js","modified":1},{"_id":"themes/next/source/js/nav-toggle.js","path":"js/nav-toggle.js","modified":1},{"_id":"themes/next/source/js/motion_global.js","path":"js/motion_global.js","modified":1},{"_id":"themes/next/source/js/motion_fallback.js","path":"js/motion_fallback.js","modified":1},{"_id":"themes/next/source/js/lazyload.js","path":"js/lazyload.js","modified":1},{"_id":"themes/next/source/js/hook-duoshuo.js","path":"js/hook-duoshuo.js","modified":1},{"_id":"themes/next/source/js/helpers.js","path":"js/helpers.js","modified":1},{"_id":"themes/next/source/js/fancy-box.js","path":"js/fancy-box.js","modified":1},{"_id":"themes/next/source/js/bootstrap.scrollspy.js","path":"js/bootstrap.scrollspy.js","modified":1},{"_id":"themes/next/source/images/weibo.png","path":"images/weibo.png","modified":1},{"_id":"themes/next/source/images/wechatpay.png","path":"images/wechatpay.png","modified":1},{"_id":"themes/next/source/images/wechat.jpg","path":"images/wechat.jpg","modified":1},{"_id":"themes/next/source/images/searchicon.png","path":"images/searchicon.png","modified":1},{"_id":"themes/next/source/images/rss.png","path":"images/rss.png","modified":1},{"_id":"themes/next/source/images/placeholder.gif","path":"images/placeholder.gif","modified":1},{"_id":"themes/next/source/images/loading.gif","path":"images/loading.gif","modified":1},{"_id":"themes/next/source/images/github.png","path":"images/github.png","modified":1},{"_id":"themes/next/source/images/cc-zero.svg","path":"images/cc-zero.svg","modified":1},{"_id":"themes/next/source/images/cc-by.svg","path":"images/cc-by.svg","modified":1},{"_id":"themes/next/source/images/cc-by-sa.svg","path":"images/cc-by-sa.svg","modified":1},{"_id":"themes/next/source/images/cc-by-nd.svg","path":"images/cc-by-nd.svg","modified":1},{"_id":"themes/next/source/images/cc-by-nc.svg","path":"images/cc-by-nc.svg","modified":1},{"_id":"themes/next/source/images/cc-by-nc-sa.svg","path":"images/cc-by-nc-sa.svg","modified":1},{"_id":"themes/next/source/images/cc-by-nc-nd.svg","path":"images/cc-by-nc-nd.svg","modified":1},{"_id":"themes/next/source/images/avatar.jpg","path":"images/avatar.jpg","modified":1},{"_id":"themes/next/source/images/alipay.png","path":"images/alipay.png","modified":1},{"_id":"themes/next/source/fonts/icon-linecons/selection.json","path":"fonts/icon-linecons/selection.json","modified":1},{"_id":"themes/next/source/fonts/icon-linecons/icomoon.woff","path":"fonts/icon-linecons/icomoon.woff","modified":1},{"_id":"themes/next/source/fonts/icon-linecons/icomoon.ttf","path":"fonts/icon-linecons/icomoon.ttf","modified":1},{"_id":"themes/next/source/fonts/icon-linecons/icomoon.svg","path":"fonts/icon-linecons/icomoon.svg","modified":1},{"_id":"themes/next/source/fonts/icon-linecons/icomoon.eot","path":"fonts/icon-linecons/icomoon.eot","modified":1},{"_id":"themes/next/source/fonts/icon-icomoon/icomoon.woff","path":"fonts/icon-icomoon/icomoon.woff","modified":1},{"_id":"themes/next/source/fonts/icon-icomoon/icomoon.ttf","path":"fonts/icon-icomoon/icomoon.ttf","modified":1},{"_id":"themes/next/source/fonts/icon-icomoon/icomoon.svg","path":"fonts/icon-icomoon/icomoon.svg","modified":1},{"_id":"themes/next/source/fonts/icon-icomoon/icomoon.eot","path":"fonts/icon-icomoon/icomoon.eot","modified":1},{"_id":"themes/next/source/fonts/icon-fifty-shades/selection.json","path":"fonts/icon-fifty-shades/selection.json","modified":1},{"_id":"themes/next/source/fonts/icon-fifty-shades/icomoon.woff","path":"fonts/icon-fifty-shades/icomoon.woff","modified":1},{"_id":"themes/next/source/fonts/icon-fifty-shades/icomoon.ttf","path":"fonts/icon-fifty-shades/icomoon.ttf","modified":1},{"_id":"themes/next/source/fonts/icon-fifty-shades/icomoon.svg","path":"fonts/icon-fifty-shades/icomoon.svg","modified":1},{"_id":"themes/next/source/fonts/icon-fifty-shades/icomoon.eot","path":"fonts/icon-fifty-shades/icomoon.eot","modified":1},{"_id":"themes/next/source/fonts/icon-feather/selection.json","path":"fonts/icon-feather/selection.json","modified":1},{"_id":"themes/next/source/fonts/icon-feather/icomoon.woff","path":"fonts/icon-feather/icomoon.woff","modified":1},{"_id":"themes/next/source/fonts/icon-feather/icomoon.ttf","path":"fonts/icon-feather/icomoon.ttf","modified":1},{"_id":"themes/next/source/fonts/icon-feather/icomoon.svg","path":"fonts/icon-feather/icomoon.svg","modified":1},{"_id":"themes/next/source/fonts/icon-feather/icomoon.eot","path":"fonts/icon-feather/icomoon.eot","modified":1},{"_id":"themes/next/source/fonts/icon-default/selection.json","path":"fonts/icon-default/selection.json","modified":1},{"_id":"themes/next/source/fonts/icon-default/icomoon.woff","path":"fonts/icon-default/icomoon.woff","modified":1},{"_id":"themes/next/source/fonts/icon-default/icomoon.ttf","path":"fonts/icon-default/icomoon.ttf","modified":1},{"_id":"themes/next/source/fonts/icon-default/icomoon.svg","path":"fonts/icon-default/icomoon.svg","modified":1},{"_id":"themes/next/source/fonts/icon-default/icomoon.eot","path":"fonts/icon-default/icomoon.eot","modified":1},{"_id":"themes/next/source/css/main.styl","path":"css/main.styl","modified":1}],"Cache":[{"_id":"source/_drafts/移动前端第三弹:这样简单的理解屏幕适配.md","shasum":"27616fd46c781201fae917fa666ea716bb80a3d9","modified":1456214724000},{"_id":"source/CNAME","shasum":"fc15c4f2799b5c37d00c728145964b89f2bc3174","modified":1452758286000},{"_id":"source/_posts/css/BFC如何应用到实际场景.md","shasum":"1eb33bc2cfe81f50c67ce09fb26a14324e6ec0bf","modified":1459219243000},{"_id":"source/_posts/css/background系列之你不知道的background-position.md","shasum":"7ab0c5da2bd1cf0275f8c5d3079ce933a62ebc5b","modified":1459219159000},{"_id":"source/_posts/css/background系列之无处不在的妙趣.md","shasum":"a1c59aeb68f60b41b5d9db1cb296bb0df31f2095","modified":1461037387000},{"_id":"source/_posts/css/margin系列之bug巡演.md","shasum":"6a7f1d54d9602f9450b17a2ebad9939eb19f5ab6","modified":1459219202000},{"_id":"source/_posts/css/margin系列之bug巡演(二).md","shasum":"b2a3c99cae226421f91617dca7a9a9fd5c124468","modified":1459219206000},{"_id":"source/_posts/css/margin系列之bug巡演(三).md","shasum":"bfa5e8e28a6aafaa44d0c3a9b5d5e9cb98be2393","modified":1459219209000},{"_id":"source/_posts/css/margin系列之keyword auto.md","shasum":"5ba6b1a143a6fe09803c75774590928d38352e2b","modified":1452758290000},{"_id":"source/_posts/css/margin系列之与相对偏移的异同.md","shasum":"d29dac0ed93674f6d5e03eecf1aa4800844d841b","modified":1459219229000},{"_id":"source/_posts/css/margin系列之内秀篇.md","shasum":"5e03b491d746350050b79e0d20cda368b1c5e37f","modified":1459219223000},{"_id":"source/_posts/css/margin系列之内秀篇(二).md","shasum":"2d433ddad834e844904affb961aeb1befc2a0c41","modified":1460449760000},{"_id":"source/_posts/css/margin系列之圣杯拾遗.md","shasum":"f5618fc78c12ced20c4fbb76ef47c4289c728693","modified":1461814390000},{"_id":"source/_posts/css/margin系列之外边距折叠.md","shasum":"042bf9fc9812c20f7f89a8bd421ee17707340094","modified":1460449618000},{"_id":"source/_posts/css/margin系列之布局篇.md","shasum":"e7440c2b49ca0e7854024052bd192887204f1751","modified":1461038483000},{"_id":"source/_posts/css/margin系列之百分比.md","shasum":"e326dfbb84bd6704e0c5718e2f8426553bd1045d","modified":1460449503000},{"_id":"source/_posts/css/你需要了解的z-index世界.md","shasum":"3678814fb6ab4950da10ba0b57b2685d9a205a4f","modified":1459219254000},{"_id":"source/_posts/css/置换和非置换元素.md","shasum":"d0b63746ba7754c57b705fd12e19a53b48d18a8f","modified":1459219250000},{"_id":"source/_posts/life/一年又要过去了.md","shasum":"51253206d81e82d34f010a0fa962183af57dcd41","modified":1459219270000},{"_id":"source/_posts/css/视觉格式化模型中的各种框.md","shasum":"09321e76f3d03ecd15b3cba3580e751544da0c13","modified":1459219247000},{"_id":"source/_posts/mobile/移动前端第一弹:viewport详解.md","shasum":"848e7fdb70514bd33cd2005177dd054ff3624f93","modified":1445250812000},{"_id":"source/_posts/mobile/移动前端第二弹:善用meta.md","shasum":"278bc6e4349cd50a5361677f83c875b706949943","modified":1456131609000},{"_id":"source/about/index.md","shasum":"74e22580dfeb94afdec2ce8f35242434140c3ed6","modified":1460978597000},{"_id":"source/categories/index.md","shasum":"fe950ab7b5b88bcf11f3a86d2304f366ce75f445","modified":1445221870000},{"_id":"source/image/adapter/iPhone.png","shasum":"868359e2c83ab4d649b94a7c86a1721c0b8a02f4","modified":1456209939000},{"_id":"source/image/boxes/anon-inline.png","shasum":"c9c18b0e538dce55196ac50ad7d14647b37b3cfb","modified":1452758286000},{"_id":"source/image/boxes/block-boxes.png","shasum":"c4631863f0bed0e2020670b461518cbe4f74c5b2","modified":1452758286000},{"_id":"source/image/boxes/inline-boxes.png","shasum":"e68da68ef01b0e60fa542959369e2adaa3e2a1bc","modified":1452758288000},{"_id":"source/tags/index.md","shasum":"47fa21d54b1e0f00b782dfdb187e85a3390777dd","modified":1445221870000},{"_id":"source/image/boxes/anon-inline.psd","shasum":"7e234cbbaf35ae4b485abd1a7b78fa3a6efb2316","modified":1452758286000},{"_id":"source/image/boxes/block-boxes.psd","shasum":"149a4055400a4ddbba6279b1524f43ec29933b92","modified":1452758288000},{"_id":"source/image/boxes/inline-boxes.psd","shasum":"b3fe4e23e98d389273ab7b1ed84526479ff67ae3","modified":1452758288000},{"_id":"themes/next/source/css/_common/_page/home.styl","shasum":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1445221870000},{"_id":"themes/next/source/css/_mixins/Mist.styl","shasum":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1445221870000},{"_id":"themes/next/source/css/_mixins/custom.styl","shasum":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1445221870000},{"_id":"themes/next/source/css/_mixins/default.styl","shasum":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1445221870000},{"_id":"themes/next/source/css/_variables/custom.styl","shasum":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1445221870000},{"_id":"themes/next/source/css/_variables/default.styl","shasum":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1445221870000},{"_id":"themes/next/README.en.md","shasum":"565ba52b3825b85a9f05b41183caca7f18b741d4","modified":1445221870000},{"_id":"themes/next/README.md","shasum":"3319de8565699fc9642f76c41ee96b50f2234b6a","modified":1445221870000},{"_id":"themes/next/_config.yml","shasum":"8db795e0830a324463bcf563d6a5804fe062a5ba","modified":1459401597000},{"_id":"themes/next/languages/de.yml","shasum":"7a8de0e5665c52a1bf168c1e7dd222c8a74fb0ab","modified":1445221870000},{"_id":"themes/next/bower.json","shasum":"1bdb0641bdcb9b5b154d2e379c57fe5675f06b9c","modified":1445221870000},{"_id":"themes/next/languages/default.yml","shasum":"7e65ef918f16d0189055deb5f1616b9dedcb1920","modified":1445221870000},{"_id":"themes/next/languages/fr-FR.yml","shasum":"6d097445342a9fb5235afea35d65bf5271b772f0","modified":1445221870000},{"_id":"themes/next/languages/en.yml","shasum":"7e65ef918f16d0189055deb5f1616b9dedcb1920","modified":1445221870000},{"_id":"themes/next/languages/ru.yml","shasum":"b4a827b9ddac9d5f6dca096fe513aeafb46a3e93","modified":1445221870000},{"_id":"themes/next/languages/zh-Hans.yml","shasum":"8af76df5557561050a950bdd7091d3bb3939c5c0","modified":1445221870000},{"_id":"themes/next/languages/zh-hk.yml","shasum":"3fc38103c9efa6f6c37149adbddb014ff85ec849","modified":1445221870000},{"_id":"themes/next/languages/zh-tw.yml","shasum":"8897a06e521b36c7a1226c72057c8357611eded8","modified":1445221870000},{"_id":"themes/next/layout/_layout.swig","shasum":"54f049f8045d386587c1e5d9761c517553b79712","modified":1452828818000},{"_id":"themes/next/layout/_macro/post-collapse.swig","shasum":"42927bdde998cefd3cf4f19b0476d69bd9e5116a","modified":1445221870000},{"_id":"themes/next/layout/_macro/post.swig","shasum":"0a6fc05731fce9718634de755116175d58cfed30","modified":1461037370000},{"_id":"themes/next/layout/_partials/footer.swig","shasum":"44d513401032362655c40cae66e579dba8dd3d85","modified":1445221870000},{"_id":"themes/next/layout/_macro/sidebar.swig","shasum":"2aa2f82042ca2391c8730992c23b09aa5b4b1c63","modified":1452861019000},{"_id":"themes/next/layout/_partials/head.swig","shasum":"1c39f49f0b40dc9febd4274953a9ac6d5f7f9066","modified":1445221870000},{"_id":"themes/next/layout/_partials/header.swig","shasum":"400eeb843e930dffcf08cc0466447f47224261c8","modified":1445221870000},{"_id":"themes/next/layout/_partials/old-browsers.swig","shasum":"dbbfea810bf3a2ed9c83b9a6683037175aacfc67","modified":1445221870000},{"_id":"themes/next/layout/_partials/pagination.swig","shasum":"d6c7f04eee4388d8f133eb5526b7c0875c321a30","modified":1445221870000},{"_id":"themes/next/layout/_partials/search/swiftype.swig","shasum":"00c2b49f6289198b0b2b4e157e4ee783277f32a7","modified":1445221870000},{"_id":"themes/next/layout/_partials/search/baidu.swig","shasum":"605ded81fba86480141764a57defde156eef0d0b","modified":1445221870000},{"_id":"themes/next/layout/_partials/search/tinysou.swig","shasum":"2f92046e0b50ebd65abb7045b1cbbfc50abbb034","modified":1445221870000},{"_id":"themes/next/layout/_partials/search.swig","shasum":"b9de6d23b2304463eb06f28f953f2570982d45b6","modified":1445221870000},{"_id":"themes/next/layout/_partials/share/duoshuo_share.swig","shasum":"89c5a5240ecb223acfe1d12377df5562a943fd5d","modified":1445221870000},{"_id":"themes/next/layout/_partials/share/jiathis.swig","shasum":"63315fcf210799f894208c9f512737096df84962","modified":1445221870000},{"_id":"themes/next/layout/_scripts/analytics/baidu-analytics.swig","shasum":"7c43d66da93cde65b473a7d6db2a86f9a42647d6","modified":1445221870000},{"_id":"themes/next/layout/_scripts/analytics/google-analytics.swig","shasum":"30a23fa7e816496fdec0e932aa42e2d13098a9c2","modified":1445221870000},{"_id":"themes/next/layout/_scripts/analytics.swig","shasum":"0ebbf76c2317faa8ba31365adba59331c2e0262c","modified":1445221870000},{"_id":"themes/next/layout/_scripts/baidushare.swig","shasum":"d726361945437cf6e48067b3dd041b7e36e98d85","modified":1445221870000},{"_id":"themes/next/layout/_scripts/bootstrap.scrollspy.swig","shasum":"85295f126836b95f0837d03e58228bb3cf8c4490","modified":1445221870000},{"_id":"themes/next/layout/_scripts/comments/disqus.swig","shasum":"3491d3cebabc8a28857200db28a1be65aad6adc2","modified":1445221870000},{"_id":"themes/next/layout/_scripts/comments/duoshuo.swig","shasum":"63b9648dcc03dc2536a7a887185fb15acfabceb4","modified":1445221870000},{"_id":"themes/next/layout/_scripts/motion.swig","shasum":"817705bfd1a1282cb6bf59094afe507e11455aa0","modified":1445221870000},{"_id":"themes/next/layout/_scripts/mathjax.swig","shasum":"abc52fefb276c52cbb19de5c214521dfcf2a10fd","modified":1445221870000},{"_id":"themes/next/layout/_scripts/fancy-box.swig","shasum":"41b4ff1446060c88c33bf666a32277dcf12129f0","modified":1445221870000},{"_id":"themes/next/layout/_scripts/helpers.swig","shasum":"4d2cbfca0aaf546a2b5813288073e824c1498fdf","modified":1445221870000},{"_id":"themes/next/layout/_scripts/pages/post-details.swig","shasum":"b63ef233886538f30ced60344ac15d25e5f3e0af","modified":1445221870000},{"_id":"themes/next/layout/archive.swig","shasum":"0c3ce594759f347ea90a4ce592a7a18e2ae4cc5c","modified":1445221870000},{"_id":"themes/next/layout/category.swig","shasum":"d6b3e1dc5e0b8deade9a084c463126e70188ee9b","modified":1445221870000},{"_id":"themes/next/layout/index.swig","shasum":"fdc801f0da71a2eb205ce9c0b12f156b219fdc9c","modified":1445221870000},{"_id":"themes/next/scripts/merge-configs.js","shasum":"dfd147d1317e56d283f5e779f00608e913603b51","modified":1445221870000},{"_id":"themes/next/scripts/tags/center-quote.js","shasum":"37274f743c2054244dcbbde56fba9ff353414281","modified":1445221870000},{"_id":"themes/next/scripts/tags/full-image.js","shasum":"0d69739d1bad5861a4a6ff2db511c3669783e438","modified":1445221870000},{"_id":"themes/next/layout/page.swig","shasum":"8019d02232a6dd1a665b6a4d2daef8e5dd2f0049","modified":1445221870000},{"_id":"themes/next/layout/post.swig","shasum":"a84457e8ced46e63bc7a8a9e0541a6ba53122a92","modified":1445221870000},{"_id":"themes/next/layout/tag.swig","shasum":"aab44af54fcbc66fea4ad12b2767ffca3eadd451","modified":1445221870000},{"_id":"themes/next/source/css/_common/_component/buttons.styl","shasum":"81063e0979f04a0f9af37f321d7321dda9abf593","modified":1445221870000},{"_id":"themes/next/source/css/_common/_component/back-to-top.styl","shasum":"88cd66910260006aa8e9e795df4948d4b67bfa11","modified":1445221870000},{"_id":"themes/next/source/css/_common/_component/comments.styl","shasum":"54e73681ba6f57ef961138f94d2ee8ac845990c3","modified":1445221870000},{"_id":"themes/next/source/css/_common/_component/duoshuo.styl","shasum":"c307f1e4827d7cb82816a5f9de109ae14ed4199c","modified":1445221870000},{"_id":"themes/next/source/css/_common/_component/jiathis.styl","shasum":"327b5f63d55ec26f7663185c1a778440588d9803","modified":1445221870000},{"_id":"themes/next/source/css/_common/_component/pagination.styl","shasum":"711c8830886619d4f4a0598b0cde5499dce50c62","modified":1445221870000},{"_id":"themes/next/source/css/_common/_component/gallery.styl","shasum":"387ce23bba52b22a586b2dfb4ec618fe1ffd3926","modified":1445221870000},{"_id":"themes/next/source/css/_common/_component/posts-collapse.styl","shasum":"8f9e8f5f65956ccf1d52ff8526392803dff579d3","modified":1445221870000},{"_id":"themes/next/source/css/_common/_component/posts-expand.styl","shasum":"4265bf1eab5e93392ed9bc9c20c93cdb74a9e062","modified":1452850537000},{"_id":"themes/next/source/css/_common/_component/posts-type.styl","shasum":"40b593134bf96d1d6095b3439d47820659d7f10b","modified":1445221870000},{"_id":"themes/next/source/css/_common/_core/base.styl","shasum":"bc6144b726b6582ae6309e2955c63eb2bcb35298","modified":1452765097000},{"_id":"themes/next/source/css/_common/_component/tag-cloud.styl","shasum":"dd8a3b22fc2f222ac6e6c05bd8a773fb039169c0","modified":1445221870000},{"_id":"themes/next/source/css/_common/_core/helpers.styl","shasum":"41a31d651b60b4f458fc56a1d191dfbbdcb6d794","modified":1445221870000},{"_id":"themes/next/source/css/_common/_core/tables.styl","shasum":"f142a185fda68bc579e89ead9a31bc8fa0f3ca8c","modified":1445221870000},{"_id":"themes/next/source/css/_common/_core/normalize.styl","shasum":"ece571f38180febaf02ace8187ead8318a300ea7","modified":1445221870000},{"_id":"themes/next/source/css/_common/_core/scaffolding.styl","shasum":"cbd7f1d5c72e3024b5d70dafb6ca93e2723652ab","modified":1445221870000},{"_id":"themes/next/source/css/_common/_fonts/icon-default.styl","shasum":"8b809aef383bebaeb3f282b47675f3a364ce3569","modified":1445221870000},{"_id":"themes/next/source/css/_common/_fonts/icon-font.styl","shasum":"ec3f86739bede393cafcd3e31052c01115ae20d6","modified":1445221870000},{"_id":"themes/next/source/css/_common/_fonts/icon-linecons.styl","shasum":"9cdbedb3627ac941cfb063b152abe5a75c3c699a","modified":1445221870000},{"_id":"themes/next/source/css/_common/_fonts/icon-feather.styl","shasum":"80413afacfa656322100ce1900fed1ebcd8f8f44","modified":1445221870000},{"_id":"themes/next/source/css/_common/_fonts/icon-fifty-shades.styl","shasum":"249f75bafa26b99d272352c0646e7497ea680b39","modified":1445221870000},{"_id":"themes/next/source/css/_common/_page/categories.styl","shasum":"4f696a2eaeee2f214adcf273eab25c62a398077a","modified":1445221870000},{"_id":"themes/next/source/css/_common/_section/body.styl","shasum":"ca1a4766cbe25baac757c6b47a4858d221afdc40","modified":1445221870000},{"_id":"themes/next/source/css/_common/_page/archive.styl","shasum":"dff879f55ca65fa79c07e9098719e53eeea7ac88","modified":1445221870000},{"_id":"themes/next/source/css/_common/_page/post-detail.styl","shasum":"73796f6f13caa7151a2ee8e55755627e0d189f55","modified":1445221870000},{"_id":"themes/next/source/css/_common/_section/footer.styl","shasum":"8994ffcce84deac0471532f270f97c44fea54dc0","modified":1445221870000},{"_id":"themes/next/source/css/_common/_section/header.styl","shasum":"ba501332fb111bd72dc0777f2e1c8a29ad538ff9","modified":1445221870000},{"_id":"themes/next/source/css/_common/_section/layout.styl","shasum":"4daaadd156ece64ae05908ad6bb0159c8a27c071","modified":1445221870000},{"_id":"themes/next/source/css/_common/_section/media.styl","shasum":"fa9809d2ecc753cf32f70803c1d0821c405211f4","modified":1445221870000},{"_id":"themes/next/source/css/_common/_section/sidebar.styl","shasum":"eac3d847e728e7af84e704dc54b8fd3f69ca8e32","modified":1452763078000},{"_id":"themes/next/source/css/_common/_vendor/highlight/highlight.styl","shasum":"a725fffc05229dd54a49760375352790fa16bf6a","modified":1452764140000},{"_id":"themes/next/source/css/_common/_vendor/highlight/theme.styl","shasum":"ae19721ceee5ba460e131cb2427dae3c1ff39d6f","modified":1445221870000},{"_id":"themes/next/source/css/_custom/custom.styl","shasum":"ed1360dfd016c40cce03421742362cabe3e581a0","modified":1445221870000},{"_id":"themes/next/source/css/_mixins/base.styl","shasum":"66985fe77bd323f7f8f634908e17166f51e96e95","modified":1445221870000},{"_id":"themes/next/source/css/_schemes/Mist/index.styl","shasum":"b1db58f0952eada96e653efc87c873a85b1016ff","modified":1452851121000},{"_id":"themes/next/source/css/_schemes/default/_menu.styl","shasum":"4bba29cece65ffc5122f4e052063dea4439fe4ae","modified":1445221870000},{"_id":"themes/next/source/css/_schemes/default/_search.styl","shasum":"c524bccdc554349106d1c8be9c3f275d4c0d4281","modified":1445221870000},{"_id":"themes/next/source/css/_schemes/default/index.styl","shasum":"2588e55132e10d82c0608f03c2c72a2bace8fa4e","modified":1445221870000},{"_id":"themes/next/source/css/_variables/Mist.styl","shasum":"f5dda1ca48c1b73a0bd34e08413de57699f24083","modified":1445221870000},{"_id":"themes/next/source/css/_variables/base.styl","shasum":"e6e4e433f2819ede904a35909fccce6d41d0d379","modified":1452764744000},{"_id":"themes/next/source/css/main.styl","shasum":"b05c342e94ded24a5f2b203cedf77d3faa817fd5","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-default/icomoon.eot","shasum":"90763e97be18be78e65749075225cceeddc6fa8a","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-default/icomoon.svg","shasum":"f92ad8cddc250f0bb5ca466fca95d321987e127e","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-default/icomoon.ttf","shasum":"c093408e6030221cafc1f79d897f1fb5283c1178","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-default/icomoon.woff","shasum":"dbe0368f2a65d87b13234cfea29d9783892fc7a8","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-default/selection.json","shasum":"dc07c29f687315f9458f6b251c214768af865fb2","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-feather/icomoon.eot","shasum":"11554b9e9d5b9f535ba96cbb27d45d8c8f1689fd","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-feather/icomoon.svg","shasum":"d5eb756eefda9b454dcb23c2b1cefd4051d18d41","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-feather/icomoon.ttf","shasum":"b2bbae4b613403cf61ad25037913378da1c07b8f","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-feather/icomoon.woff","shasum":"2ea1c59c17422798e64ee6f4e9ce1f7aff1a06a5","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-feather/selection.json","shasum":"06ea91e3f98ebe1080087acad4356802bc5b6ebf","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-fifty-shades/icomoon.eot","shasum":"da86ba5df72d1288de9e9633e5f528062dd427d5","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-fifty-shades/icomoon.woff","shasum":"4de6a74f523dee33d95dde61caae5809f9a5d448","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-fifty-shades/icomoon.ttf","shasum":"72fe82e1f3db52414eed706952d385af241cb196","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-fifty-shades/icomoon.svg","shasum":"1a4afd739e1f8eb8d430dbdd29e36a9999802e8d","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-fifty-shades/selection.json","shasum":"fdd09098d1c3688e2c88cf33fd51e76b383b6d7f","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-icomoon/icomoon.eot","shasum":"301fcf00c24750dddf1c529f944ca62c7f1a217d","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-icomoon/icomoon.svg","shasum":"e316347805eb93425faa678611c5e42a7152da8f","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-icomoon/icomoon.ttf","shasum":"f399713d1c9400d4d3373e38991a7e362a754a94","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-icomoon/icomoon.woff","shasum":"05f1ec0bd307da5e731a86eb4961589a6042aebb","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-linecons/icomoon.eot","shasum":"e2d7f040428a632f3c50bfa94083b759936effc2","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-linecons/icomoon.svg","shasum":"808eaf7d61f7e67c76976265c885e79c36920f0b","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-linecons/icomoon.woff","shasum":"0b07ee6ceda3b1bceb40c1e7379b3aa48dcc15a8","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-linecons/icomoon.ttf","shasum":"078068206684e4f185b0187ad3cee16f54a287d7","modified":1445221870000},{"_id":"themes/next/source/fonts/icon-linecons/selection.json","shasum":"db4ce25d31449ecc6685b32e145252103967bb5c","modified":1445221870000},{"_id":"themes/next/source/images/alipay.png","shasum":"ee1c019d5840e02149079390c6791943e5908865","modified":1460978147000},{"_id":"themes/next/source/images/cc-by-nc-nd.svg","shasum":"c6524ece3f8039a5f612feaf865d21ec8a794564","modified":1445221870000},{"_id":"themes/next/source/images/cc-by-nc.svg","shasum":"8d39b39d88f8501c0d27f8df9aae47136ebc59b7","modified":1445221870000},{"_id":"themes/next/source/images/cc-by-nd.svg","shasum":"c563508ce9ced1e66948024ba1153400ac0e0621","modified":1445221870000},{"_id":"themes/next/source/images/cc-by-nc-sa.svg","shasum":"3031be41e8753c70508aa88e84ed8f4f653f157e","modified":1445221870000},{"_id":"themes/next/source/images/cc-by-sa.svg","shasum":"aa4742d733c8af8d38d4c183b8adbdcab045872e","modified":1445221870000},{"_id":"themes/next/source/images/cc-zero.svg","shasum":"87669bf8ac268a91d027a0a4802c92a1473e9030","modified":1445221870000},{"_id":"themes/next/source/images/cc-by.svg","shasum":"28a0a4fe355a974a5e42f68031652b76798d4f7e","modified":1445221870000},{"_id":"themes/next/source/images/github.png","shasum":"b84d03b32fa388dcbf149296ebd16dce6223d48d","modified":1452760835000},{"_id":"themes/next/source/images/loading.gif","shasum":"5fbd472222feb8a22cf5b8aa5dc5b8e13af88e2b","modified":1445221870000},{"_id":"themes/next/source/images/placeholder.gif","shasum":"5fbd472222feb8a22cf5b8aa5dc5b8e13af88e2b","modified":1445221870000},{"_id":"themes/next/source/images/rss.png","shasum":"430fd47340e75214c081abd05cd7410cf7c71b86","modified":1452760845000},{"_id":"themes/next/source/images/searchicon.png","shasum":"67727a6a969be0b2659b908518fa6706eed307b8","modified":1445221870000},{"_id":"themes/next/source/images/weibo.png","shasum":"280dae3fd38086158b4a1b57edb94c06b1a5014b","modified":1452760842000},{"_id":"themes/next/source/images/wechatpay.png","shasum":"3874ef18c92a3c709343950811f2a3ac2fc08ceb","modified":1460978252000},{"_id":"themes/next/source/js/bootstrap.scrollspy.js","shasum":"ae7bdce88b515aade4eea8bf7407eec458bcd625","modified":1445221870000},{"_id":"themes/next/source/js/fancy-box.js","shasum":"c9782bfa8c1e51a8f8541530d836e75f48a433c2","modified":1445221870000},{"_id":"themes/next/source/js/helpers.js","shasum":"c2117b0ec653df4c45dd9d9575b190cbe1035335","modified":1445221870000},{"_id":"themes/next/source/js/lazyload.js","shasum":"b92e9acdc7afc15468314c03f4a643b0c93944cf","modified":1445221870000},{"_id":"themes/next/source/js/hook-duoshuo.js","shasum":"ea30e91c6b7fdaa6dce4a848f25cdf90436b072a","modified":1445221870000},{"_id":"themes/next/source/js/motion_fallback.js","shasum":"a767d522c65a8b2fbad49135c9332135c6785c3e","modified":1445221870000},{"_id":"themes/next/source/js/motion_global.js","shasum":"367e329b2cc19c6b7634ea2917a218c84a22ec17","modified":1445221870000},{"_id":"themes/next/source/js/nav-toggle.js","shasum":"78b59f1beb12adea0d7f9bcf4377cb699963f220","modified":1445221870000},{"_id":"themes/next/source/js/ua-parser.min.js","shasum":"acf0ee6a47ffb7231472b56e43996e3f947c258a","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/blank.gif","shasum":"2daeaa8b5f19f0bc209d976c02bd6acb51b00b0a","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/fancybox_loading.gif","shasum":"1a755fb2599f3a313cc6cfdb14df043f8c14a99c","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/[email protected]","shasum":"273b123496a42ba45c3416adb027cd99745058b0","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/fancybox_overlay.png","shasum":"b3a4ee645ba494f52840ef8412015ba0f465dbe0","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/fancybox_sprite.png","shasum":"17df19f97628e77be09c352bf27425faea248251","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/[email protected]","shasum":"30c58913f327e28f466a00f4c1ac8001b560aed8","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/helpers/fancybox_buttons.png","shasum":"e385b139516c6813dcd64b8fc431c364ceafe5f3","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/helpers/jquery.fancybox-buttons.css","shasum":"1a9d8e5c22b371fcc69d4dbbb823d9c39f04c0c8","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/helpers/jquery.fancybox-buttons.js","shasum":"91e41741c2e93f732c82aaacec4cfc6e3f3ec876","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/helpers/jquery.fancybox-media.js","shasum":"3bdf69ed2469e4fb57f5a95f17300eef891ff90d","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/helpers/jquery.fancybox-thumbs.css","shasum":"4ac329c16a5277592fc12a37cca3d72ca4ec292f","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/jquery.fancybox.css","shasum":"5f163444617b6cf267342f06ac166a237bb62df9","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/helpers/jquery.fancybox-thumbs.js","shasum":"53e194f4a72e649c04fb586dd57762b8c022800b","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/jquery.fancybox.js","shasum":"1cf3d47b5ccb7cb6e9019c64f2a88d03a64853e4","modified":1445221870000},{"_id":"themes/next/source/vendors/fastclick/LICENSE","shasum":"dcd5b6b43095d9e90353a28b09cb269de8d4838e","modified":1445221870000},{"_id":"themes/next/source/vendors/fancybox/source/jquery.fancybox.pack.js","shasum":"53360764b429c212f424399384417ccc233bb3be","modified":1445221870000},{"_id":"themes/next/source/vendors/fastclick/README.md","shasum":"1decd8e1adad2cd6db0ab50cf56de6035156f4ea","modified":1445221870000},{"_id":"themes/next/source/vendors/fastclick/bower.json","shasum":"13379463c7463b4b96d13556b46faa4cc38d81e6","modified":1445221870000},{"_id":"themes/next/source/vendors/fastclick/lib/fastclick.js","shasum":"06cef196733a710e77ad7e386ced6963f092dc55","modified":1445221870000},{"_id":"themes/next/source/vendors/fastclick/lib/fastclick.min.js","shasum":"2cae0f5a6c5d6f3cb993015e6863f9483fc4de18","modified":1445221870000},{"_id":"themes/next/source/vendors/velocity/bower.json","shasum":"2ec99573e84c7117368beccb9e94b6bf35d2db03","modified":1445221870000},{"_id":"themes/next/source/vendors/velocity/velocity.min.js","shasum":"2f1afadc12e4cf59ef3b405308d21baa97e739c6","modified":1445221870000},{"_id":"themes/next/source/vendors/velocity/velocity.ui.js","shasum":"6a1d101eab3de87527bb54fcc8c7b36b79d8f0df","modified":1445221870000},{"_id":"themes/next/source/vendors/velocity/velocity.ui.min.js","shasum":"ed5e534cd680a25d8d14429af824f38a2c7d9908","modified":1445221870000},{"_id":"themes/next/test/helpers.js","shasum":"a1f5de25154c3724ffc24a91ddc576cdbd60864f","modified":1445221870000},{"_id":"themes/next/test/intern.js","shasum":"11fa8a4f5c3b4119a179ae0a2584c8187f907a73","modified":1445221870000},{"_id":"themes/next/source/images/avatar.jpg","shasum":"f7513b63ba44aacc563e19ed86adf3429e74e64d","modified":1452763001000},{"_id":"themes/next/source/images/wechat.jpg","shasum":"bb1f7659af48bd059109426dc01e79434acb2c17","modified":1459242540000},{"_id":"themes/next/source/vendors/jquery/index.js","shasum":"41b4bfbaa96be6d1440db6e78004ade1c134e276","modified":1445221870000},{"_id":"themes/next/source/vendors/velocity/velocity.js","shasum":"e63dc7cea055ca60a95d286f32349d88b10c5a4d","modified":1445221870000}],"Category":[{"name":"mobile","_id":"cinjqvafu00042ypk22zb1u2c"},{"name":"life","_id":"cinjqvag2000l2ypk2hojf81x"},{"name":"CSS","_id":"cinjqvag5000s2ypkn7t4myl4"}],"Data":[],"Page":[{"title":"标签","date":"2015-10-04T06:47:57.000Z","type":"tags","_content":"","source":"tags/index.md","raw":"title: 标签\ndate: 2015-10-04 14:47:57\ntype: tags\n---\n","updated":"2015-10-19T02:31:10.000Z","path":"tags/index.html","comments":1,"layout":"page","_id":"cinjqvaf500002ypkxo3x10au"},{"title":"分类","date":"2015-10-04T06:49:36.000Z","type":"categories","_content":"","source":"categories/index.md","raw":"title: 分类\ndate: 2015-10-04 14:49:36\ntype: categories\n---\n","updated":"2015-10-19T02:31:10.000Z","path":"categories/index.html","comments":1,"layout":"page","_id":"cinjqvafm00012ypkwhpi5r63"},{"title":"关于我","date":"2013-11-27T03:15:00.000Z","tags":["简历","自我介绍"],"type":"about","_content":"\n## 关于\n\n博主真名叫杜瑶,网络上陆续用过一些昵称,比如:飘零雾雨、Joy Du、doyoe。\n\n但其实博主自己只在中学时取过 `飘零雾雨` 这一个昵称,其他的都算是阴差阳错而来。`Joy` 是我的英文名,用的不多;而 `doyoe` 实则是我的域名。由于有些站点不允许过短的用户名,所以不少地方博主直接用了 `doyoe` 这个名称注册,因为这对博主来讲是记忆成本最低的字母组合,然后好多童鞋以为我叫这个。不过连博主自己都不知道 `doyoe` 要怎么发音,因为它甚至都不是一个有效的单词。\n\n当然,现在我又多了一个不知道起源的新昵称:`瑶姐`。所以大家能记住哪个就用哪个,只要博主知道你们是在和我说话就行。\n\n## 职业\n\n博主目前在帝都,任职于[去哪儿网](http://www.qunar.com/),对去哪儿网感兴趣的童鞋,欢迎艾特我的微博 [@doyoe](http://weibo.com/doyoe)。\n\n## 版权申明\n\n本站的文章都是原创,大家可以随意转载,只需留有原文出处即可。\n\n另外:由于技术类的文章,可能都会有一定的时效性,大家在阅读文章时,请保持谨慎,因为可能你正在阅读的文章已经过时。博主会持续维护本站的文章,但博主无法通知转载者对文章进行更新。为了不给读者造成困扰或误导,请大家在转载时加上原文出处。\n\n## 赞助本站\n\n如果你认为我的文章对你有帮助,欢迎赞助本站\n\n![微信](/images/wechatpay.png)\n![支付宝](/images/alipay.png)\n\n当然,你的留言互动也是一种对博主支持方式,请不要吝惜文字表达。\n\n## 我的站点:\n* [飘雨社区](http://www.doyoe.com/)\n* [CSS探索之旅](http://blog.doyoe.com/) [GitHub](https://github.com/doyoe/blog)\n* [Web前端实验室](http://demo.doyoe.com/)\n* [CSS参考手册](http://css.doyoe.com/) [GitHub](https://github.com/doyoe/css-handbook)","source":"about/index.md","raw":"title: 关于我\ndate: 2013-11-27 11:15:00\ntags: [简历, 自我介绍]\ntype: about\n---\n\n## 关于\n\n博主真名叫杜瑶,网络上陆续用过一些昵称,比如:飘零雾雨、Joy Du、doyoe。\n\n但其实博主自己只在中学时取过 `飘零雾雨` 这一个昵称,其他的都算是阴差阳错而来。`Joy` 是我的英文名,用的不多;而 `doyoe` 实则是我的域名。由于有些站点不允许过短的用户名,所以不少地方博主直接用了 `doyoe` 这个名称注册,因为这对博主来讲是记忆成本最低的字母组合,然后好多童鞋以为我叫这个。不过连博主自己都不知道 `doyoe` 要怎么发音,因为它甚至都不是一个有效的单词。\n\n当然,现在我又多了一个不知道起源的新昵称:`瑶姐`。所以大家能记住哪个就用哪个,只要博主知道你们是在和我说话就行。\n\n## 职业\n\n博主目前在帝都,任职于[去哪儿网](http://www.qunar.com/),对去哪儿网感兴趣的童鞋,欢迎艾特我的微博 [@doyoe](http://weibo.com/doyoe)。\n\n## 版权申明\n\n本站的文章都是原创,大家可以随意转载,只需留有原文出处即可。\n\n另外:由于技术类的文章,可能都会有一定的时效性,大家在阅读文章时,请保持谨慎,因为可能你正在阅读的文章已经过时。博主会持续维护本站的文章,但博主无法通知转载者对文章进行更新。为了不给读者造成困扰或误导,请大家在转载时加上原文出处。\n\n## 赞助本站\n\n如果你认为我的文章对你有帮助,欢迎赞助本站\n\n![微信](/images/wechatpay.png)\n![支付宝](/images/alipay.png)\n\n当然,你的留言互动也是一种对博主支持方式,请不要吝惜文字表达。\n\n## 我的站点:\n* [飘雨社区](http://www.doyoe.com/)\n* [CSS探索之旅](http://blog.doyoe.com/) [GitHub](https://github.com/doyoe/blog)\n* [Web前端实验室](http://demo.doyoe.com/)\n* [CSS参考手册](http://css.doyoe.com/) [GitHub](https://github.com/doyoe/css-handbook)","updated":"2016-04-18T11:23:17.000Z","path":"about/index.html","comments":1,"layout":"page","_id":"cinjqvafo00022ypk7klocox3"}],"Post":[{"title":"移动前端第二弹:善用meta","date":"2015-10-20T08:00:11.000Z","author":"杜瑶","_content":"\n## 前言\n\n在[移动前端第一弹:viewport详解](/2015/10/13/mobile/移动前端第一弹:viewport详解/)中,我们讲了`viewport`,那是一个关于`meta`的故事。这次我们会就将`meta`这个故事讲得更广阔、更有意思一些。\n\n写过`HTML`的童鞋,应该都对这个不陌生,或用它来定义页面编码,或用它来定义搜索引擎抓取方式,或用它定义页面关键字,描述等等。\n\n## meta列表\n\n好的`meta`使用,能更好地提高页面的可用性及被检索的几率。\n\n这里并不会列出所有的`meta`使用方式,只挑选一些常用及实际意义比较大的讲讲,当然也包括一些厂商私有定制的。\n\n<!--more-->\n\n### 常规\n\n#### 声明文档使用的字符编码\n```\n<meta charset=\"utf-8\" />\n```\n该声明用来指定文档的编码,除了`utf-8`,可选值还有:ISO-8859-1、BIG5、iso-8859-2, iso-2022-jp, iso-2022-kr, gb2312等\n\n当然,你可能还见过使用另外一种方式来定义文档字符编码:\n```\n<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n```\n相对于这种方式,更推荐你使用第1种,言外之意,就是推荐使用`HTML5`。\n\n\n#### 声明页面刷新或跳转\n```\n<meta http-equiv=\"refresh\" content=\"10\" />\n<meta http-equiv=\"refresh\" content=\"10; url=http://www.doyoe.com\" />\n```\n该声明用来指定页面自刷新或者跳转到其它页面,其中的时间单位是`s`。\n\n\n#### 声明页面过期时间\n```\n<meta http-equiv=\"expires\" content=\"0\" />\n<meta http-equiv=\"expires\" content=\"Wed, 26 Feb 1997 08:21:57 GMT\" />\n```\n该声明用来指定页面的过期时间,一旦网页过期,从服务器上重新请求,其中时间必须使用`GMT`格式,或者直接是`0`(即不缓存)\n\n\n#### 声明页面是否缓存\n```\n<meta http-equiv=\"pragma\" content=\"no-cache\" />\n<meta http-equiv=\"cache-control\" content=\"no-cache\" />\n```\n上述语句都可以用来指定文档不被缓存。一些仍然在使用HTTP/1.0的可以使用第1条,第2条由HTTP/1.1提供,常用值还有:public, no-cache, no-store等\n\n\n\n#### 声明作者信息\n```\n<meta name=\"author\" content=\"joy, [email protected]\" />\n```\n\n\n#### 声明文档关键字\n```\n<meta name=\"keywords\" content=\"CSS, HTML, JavaScript, 前端\" />\n```\n多关键字之间以半角逗号分隔\n\n\n#### 声明文档描述\n```\n<meta name=\"description\" content=\"这是一份meta列表\" />\n```\n文档描述内容最好是完整的一句话,以不超过50个字符为宜\n\n\n#### 声明使用的浏览器及版本\n`x-ua-compatible`设置是从`IE8`开始增加的(很明显,只适用于IE),对于过往的版本无法识别。\n开发者可以通过设置`x-ua-compatible`来指定渲染引擎的类型和版本,并且因为需求不同可以有多种不同的设置:\n\n##### Case1:\n```\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=7\" />\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=4\" />\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=xx\" />\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=50\" />\n```\n当直接指定`content`为`IE的某个具体版本`,如上述代码第1条,客户端的IE将会使用IE7.0标准模式对页面进行渲染,并忽略Doctype定义。\n**当指定的IE版本在客户端IE中不存在时,IE将会尝试将该值转换为最为接近的版本。**\n例如指定一个错误的或者低于5.0的IE版本,如上述代码第2,3条,客户端的IE将会使用IE5.0对页面进行渲染,由于IE5.0并没有标准模式,所以将会直接使用`quirks mode`来渲染;\n如果指定一个大于客户端IE的版本,如上述代码第4条,假定客户端IE的最高版本为9.0,那么IE会将该值转换为`IE=9`,即使用IE9.0标准模式对页面进行渲染。\n\n##### Case2:\n```\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=EmulateIE7\" />\n```\n当指定的`content`值加了`Emulate`前缀时,如上述代码,客户端IE将会根据Doctype定义来决定如何来对页面进行渲染。假设页面使用了标准的Doctype,那么此定义效果等同`Case1`;假设页面并没有使用标准的Doctype,那么将使用`quirks mode`来渲染。\n\n##### Case3:\n```\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=Edge\" />\n```\n当指定的`content`值为`IE=Edge`时,如上述代码,客户端的IE将会使用最高的标准模式对页面进行渲染。\n\n##### Case4:\n```\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=7, 10, 11\" />\n```\n当指定的`content`值有多个版本时,如上述代码,假定客户端IE版本为8.0或者9.0,则使用IE7.0标准模式对页面进行渲染;假定客户端IE版本为10.0或者11.0,则直接使用对应版本的标准模式对页面进行渲染。\n\n##### Case5:\n```\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=Edge, chrome=1\" />\n```\n当指定的`content`值为`IE=Edge, chrome=1`时,如上述代码,假定客户端安装了`Google Chrome Frame`,则在IE中使用chrome的渲染引擎来渲染页面,否则,将会使用客户端IE最高的标准模式对页面进行渲染。\n\n\n#### 声明搜索引擎抓取方式\n```\n<meta name=\"robots\" content=\"index\" />\n```\n通知搜索引擎文档是否需要被索引。可选值有:\n\n* all(默认值,索引当前页并跟踪链接,相当于:index, follow)\n* none(忽略当前页,相当于:noindex, nofollow)\n* index(索引当前页)\n* noindex(不索引当前页)\n* follow(跟踪当前页链接,不论当前页是否被索引)\n* nofollow(不跟踪当前页链接,不论当前页是否被索引)\n\n如果声明冲突,某些引擎可能会做严格处理:\n```\n<meta name=\"robots\" content=\"noindex\" />\n<meta name=\"robots\" content=\"index\" />\n```\n类似上述代码,在`Google`引擎中,会执行`noindex`这个更为严格的声明。\n\n需要注意的是并不是所有搜索引擎都支持`robots meta`,比较保守的做法是配合`robots.txt`使用。\n\n\n#### 声明搜索引擎抓取间隔\n```\n<meta name=\"revisit-after\" content=\"10 days\" />\n```\n有时候你可能并不希望站点一直被搜索引擎抓取,而是每间隔一段时间才来访问一次,这时,可以声明`revisit-after meta`。\n\n### 移动\n\n#### 声明viewport视口\n```\n<meta name=\"viewport\" content=\"initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no\" />\n```\n该声明用于指定在移动设备上页面的布局视口如何设置。对于`viewport meta`的详细设置,请参考:[移动前端第一弹:viewport详解](/2015/10/13/mobile/移动前端第一弹:viewport详解/)\n\n\n#### 声明添加到主屏幕的Web App标题\n`iOS Safari`允许用户将一个网页添加到主屏幕然后像`App`一样来操作它。我们知道每个`App`下方都会有一个名字,`iOS Safari`提供了一个私有的`meta`来定义这个名字,代码如下:\n```\n<meta name=\"apple-mobile-web-app-title\" content=\"Web App名称\" />\n```\n`Android Chrome31.0`,`Android Browser5.0`也开始支持添加到主屏幕了,但并没有提供相应的定义标题的方式,所以如果你想统一`iOS`和`Android`平台定义`Web app`名称的方式,可以使用`title`标签来定义,代码如下:\n```\n<title>Web App名称</title>\n```\n但如果你想要网页标题和App名字不一样的话,那就只有iOS才行。\n\n\n#### 声明添加到主屏幕时隐藏地址栏和状态栏(即全屏)\n当我们将一个网页添加到主屏幕时,会更希望它能有像`App`一样的表现,没有地址栏和状态栏全屏显示,代码如下:\n```\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n```\n该方案在 `iOS` 和 `Android5.0+` 上都通用。\n\n\n#### 声明添加到主屏幕时设置系统顶栏颜色\n当我们将一个网页添加到主屏幕时,还可以对 `系统显示手机信号、时间、电池的顶部状态栏` 颜色进行设置,前提是开启了:\n```\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n```\n有了这个前提,你可以通过下面的方式来进行定义:\n```\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\" />\n```\ncontent只有3个固定值可选:default | black | black-translucent\n\n* 如果设置为 `default`,状态栏将为正常的,即白色,网页从状态栏以下开始显示;\n* 如果设置为 `black`,状态栏将为黑色,网页从状态栏以下开始显示;\n* 如果设置为 `black-translucent`,状态栏将为灰色半透明,网页将充满整个屏幕,状态栏会盖在网页之上;\n\n该设置只在 `iOS` 上有效。\n\n\n#### 电话号码识别\n在 `iOS Safari` (其他浏览器和Android均不会)上会对那些看起来像是电话号码的数字处理为电话链接,比如:\n\n* 7位数字,形如:1234567\n* 带括号及加号的数字,形如:(+86)123456789\n* 双连接线的数字,形如:00-00-00111\n* 11位数字,形如:13800138000\n\n可能还有其他类型的数字也会被识别,但在具体的业务场景中,有些时候这是不必须的,所以你可以关闭电话自动识别,然后在需要拨号的地方,开启电话呼出和短信功能。\n\n1. 关闭电话号码识别:\n```\n<meta name=\"format-detection\" content=\"telephone=no\" />\n```\n\n2. 开启拨打电话功能:\n```\n<a href=\"tel:123456\">123456</a>\n```\n\n3. 开启发送短信功能:\n```\n<a href=\"sms:123456\">123456</a>\n```\n\n\n#### 邮箱地址识别\n在 `Android` (iOS不会)上,浏览器会自动识别看起来像邮箱地址的字符串,不论有你没有加上邮箱链接,当你在这个字符串上长按,会弹出发邮件的提示。\n\n1. 关闭邮箱地址识别:\n```\n<meta name=\"format-detection\" content=\"email=no\" />\n```\n\n2. 开启邮件发送:\n```\n<a href=\"mailto:[email protected]\">[email protected]</a>\n```\n\n3. 如果想同时关闭电话和邮箱识别,可以把它们写到一条 meta 内,代码如下:\n```\n<meta name=\"format-detection\" content=\"telephone=no,email=no\" />\n```\n\n\n## 附注\n\n部分`meta`定义来自于[trip](https://github.com/doyoe/trip)","source":"_posts/mobile/移动前端第二弹:善用meta.md","raw":"title: 移动前端第二弹:善用meta\ndate: 2015-10-20 16:00:11\nauthor: 杜瑶\ncategories: mobile\ntags: [HTML5, meta, meta大全, meta列表]\n---\n\n## 前言\n\n在[移动前端第一弹:viewport详解](/2015/10/13/mobile/移动前端第一弹:viewport详解/)中,我们讲了`viewport`,那是一个关于`meta`的故事。这次我们会就将`meta`这个故事讲得更广阔、更有意思一些。\n\n写过`HTML`的童鞋,应该都对这个不陌生,或用它来定义页面编码,或用它来定义搜索引擎抓取方式,或用它定义页面关键字,描述等等。\n\n## meta列表\n\n好的`meta`使用,能更好地提高页面的可用性及被检索的几率。\n\n这里并不会列出所有的`meta`使用方式,只挑选一些常用及实际意义比较大的讲讲,当然也包括一些厂商私有定制的。\n\n<!--more-->\n\n### 常规\n\n#### 声明文档使用的字符编码\n```\n<meta charset=\"utf-8\" />\n```\n该声明用来指定文档的编码,除了`utf-8`,可选值还有:ISO-8859-1、BIG5、iso-8859-2, iso-2022-jp, iso-2022-kr, gb2312等\n\n当然,你可能还见过使用另外一种方式来定义文档字符编码:\n```\n<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n```\n相对于这种方式,更推荐你使用第1种,言外之意,就是推荐使用`HTML5`。\n\n\n#### 声明页面刷新或跳转\n```\n<meta http-equiv=\"refresh\" content=\"10\" />\n<meta http-equiv=\"refresh\" content=\"10; url=http://www.doyoe.com\" />\n```\n该声明用来指定页面自刷新或者跳转到其它页面,其中的时间单位是`s`。\n\n\n#### 声明页面过期时间\n```\n<meta http-equiv=\"expires\" content=\"0\" />\n<meta http-equiv=\"expires\" content=\"Wed, 26 Feb 1997 08:21:57 GMT\" />\n```\n该声明用来指定页面的过期时间,一旦网页过期,从服务器上重新请求,其中时间必须使用`GMT`格式,或者直接是`0`(即不缓存)\n\n\n#### 声明页面是否缓存\n```\n<meta http-equiv=\"pragma\" content=\"no-cache\" />\n<meta http-equiv=\"cache-control\" content=\"no-cache\" />\n```\n上述语句都可以用来指定文档不被缓存。一些仍然在使用HTTP/1.0的可以使用第1条,第2条由HTTP/1.1提供,常用值还有:public, no-cache, no-store等\n\n\n\n#### 声明作者信息\n```\n<meta name=\"author\" content=\"joy, [email protected]\" />\n```\n\n\n#### 声明文档关键字\n```\n<meta name=\"keywords\" content=\"CSS, HTML, JavaScript, 前端\" />\n```\n多关键字之间以半角逗号分隔\n\n\n#### 声明文档描述\n```\n<meta name=\"description\" content=\"这是一份meta列表\" />\n```\n文档描述内容最好是完整的一句话,以不超过50个字符为宜\n\n\n#### 声明使用的浏览器及版本\n`x-ua-compatible`设置是从`IE8`开始增加的(很明显,只适用于IE),对于过往的版本无法识别。\n开发者可以通过设置`x-ua-compatible`来指定渲染引擎的类型和版本,并且因为需求不同可以有多种不同的设置:\n\n##### Case1:\n```\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=7\" />\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=4\" />\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=xx\" />\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=50\" />\n```\n当直接指定`content`为`IE的某个具体版本`,如上述代码第1条,客户端的IE将会使用IE7.0标准模式对页面进行渲染,并忽略Doctype定义。\n**当指定的IE版本在客户端IE中不存在时,IE将会尝试将该值转换为最为接近的版本。**\n例如指定一个错误的或者低于5.0的IE版本,如上述代码第2,3条,客户端的IE将会使用IE5.0对页面进行渲染,由于IE5.0并没有标准模式,所以将会直接使用`quirks mode`来渲染;\n如果指定一个大于客户端IE的版本,如上述代码第4条,假定客户端IE的最高版本为9.0,那么IE会将该值转换为`IE=9`,即使用IE9.0标准模式对页面进行渲染。\n\n##### Case2:\n```\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=EmulateIE7\" />\n```\n当指定的`content`值加了`Emulate`前缀时,如上述代码,客户端IE将会根据Doctype定义来决定如何来对页面进行渲染。假设页面使用了标准的Doctype,那么此定义效果等同`Case1`;假设页面并没有使用标准的Doctype,那么将使用`quirks mode`来渲染。\n\n##### Case3:\n```\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=Edge\" />\n```\n当指定的`content`值为`IE=Edge`时,如上述代码,客户端的IE将会使用最高的标准模式对页面进行渲染。\n\n##### Case4:\n```\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=7, 10, 11\" />\n```\n当指定的`content`值有多个版本时,如上述代码,假定客户端IE版本为8.0或者9.0,则使用IE7.0标准模式对页面进行渲染;假定客户端IE版本为10.0或者11.0,则直接使用对应版本的标准模式对页面进行渲染。\n\n##### Case5:\n```\n<meta http-equiv=\"x-ua-compatible\" content=\"IE=Edge, chrome=1\" />\n```\n当指定的`content`值为`IE=Edge, chrome=1`时,如上述代码,假定客户端安装了`Google Chrome Frame`,则在IE中使用chrome的渲染引擎来渲染页面,否则,将会使用客户端IE最高的标准模式对页面进行渲染。\n\n\n#### 声明搜索引擎抓取方式\n```\n<meta name=\"robots\" content=\"index\" />\n```\n通知搜索引擎文档是否需要被索引。可选值有:\n\n* all(默认值,索引当前页并跟踪链接,相当于:index, follow)\n* none(忽略当前页,相当于:noindex, nofollow)\n* index(索引当前页)\n* noindex(不索引当前页)\n* follow(跟踪当前页链接,不论当前页是否被索引)\n* nofollow(不跟踪当前页链接,不论当前页是否被索引)\n\n如果声明冲突,某些引擎可能会做严格处理:\n```\n<meta name=\"robots\" content=\"noindex\" />\n<meta name=\"robots\" content=\"index\" />\n```\n类似上述代码,在`Google`引擎中,会执行`noindex`这个更为严格的声明。\n\n需要注意的是并不是所有搜索引擎都支持`robots meta`,比较保守的做法是配合`robots.txt`使用。\n\n\n#### 声明搜索引擎抓取间隔\n```\n<meta name=\"revisit-after\" content=\"10 days\" />\n```\n有时候你可能并不希望站点一直被搜索引擎抓取,而是每间隔一段时间才来访问一次,这时,可以声明`revisit-after meta`。\n\n### 移动\n\n#### 声明viewport视口\n```\n<meta name=\"viewport\" content=\"initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no\" />\n```\n该声明用于指定在移动设备上页面的布局视口如何设置。对于`viewport meta`的详细设置,请参考:[移动前端第一弹:viewport详解](/2015/10/13/mobile/移动前端第一弹:viewport详解/)\n\n\n#### 声明添加到主屏幕的Web App标题\n`iOS Safari`允许用户将一个网页添加到主屏幕然后像`App`一样来操作它。我们知道每个`App`下方都会有一个名字,`iOS Safari`提供了一个私有的`meta`来定义这个名字,代码如下:\n```\n<meta name=\"apple-mobile-web-app-title\" content=\"Web App名称\" />\n```\n`Android Chrome31.0`,`Android Browser5.0`也开始支持添加到主屏幕了,但并没有提供相应的定义标题的方式,所以如果你想统一`iOS`和`Android`平台定义`Web app`名称的方式,可以使用`title`标签来定义,代码如下:\n```\n<title>Web App名称</title>\n```\n但如果你想要网页标题和App名字不一样的话,那就只有iOS才行。\n\n\n#### 声明添加到主屏幕时隐藏地址栏和状态栏(即全屏)\n当我们将一个网页添加到主屏幕时,会更希望它能有像`App`一样的表现,没有地址栏和状态栏全屏显示,代码如下:\n```\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n```\n该方案在 `iOS` 和 `Android5.0+` 上都通用。\n\n\n#### 声明添加到主屏幕时设置系统顶栏颜色\n当我们将一个网页添加到主屏幕时,还可以对 `系统显示手机信号、时间、电池的顶部状态栏` 颜色进行设置,前提是开启了:\n```\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n```\n有了这个前提,你可以通过下面的方式来进行定义:\n```\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\" />\n```\ncontent只有3个固定值可选:default | black | black-translucent\n\n* 如果设置为 `default`,状态栏将为正常的,即白色,网页从状态栏以下开始显示;\n* 如果设置为 `black`,状态栏将为黑色,网页从状态栏以下开始显示;\n* 如果设置为 `black-translucent`,状态栏将为灰色半透明,网页将充满整个屏幕,状态栏会盖在网页之上;\n\n该设置只在 `iOS` 上有效。\n\n\n#### 电话号码识别\n在 `iOS Safari` (其他浏览器和Android均不会)上会对那些看起来像是电话号码的数字处理为电话链接,比如:\n\n* 7位数字,形如:1234567\n* 带括号及加号的数字,形如:(+86)123456789\n* 双连接线的数字,形如:00-00-00111\n* 11位数字,形如:13800138000\n\n可能还有其他类型的数字也会被识别,但在具体的业务场景中,有些时候这是不必须的,所以你可以关闭电话自动识别,然后在需要拨号的地方,开启电话呼出和短信功能。\n\n1. 关闭电话号码识别:\n```\n<meta name=\"format-detection\" content=\"telephone=no\" />\n```\n\n2. 开启拨打电话功能:\n```\n<a href=\"tel:123456\">123456</a>\n```\n\n3. 开启发送短信功能:\n```\n<a href=\"sms:123456\">123456</a>\n```\n\n\n#### 邮箱地址识别\n在 `Android` (iOS不会)上,浏览器会自动识别看起来像邮箱地址的字符串,不论有你没有加上邮箱链接,当你在这个字符串上长按,会弹出发邮件的提示。\n\n1. 关闭邮箱地址识别:\n```\n<meta name=\"format-detection\" content=\"email=no\" />\n```\n\n2. 开启邮件发送:\n```\n<a href=\"mailto:[email protected]\">[email protected]</a>\n```\n\n3. 如果想同时关闭电话和邮箱识别,可以把它们写到一条 meta 内,代码如下:\n```\n<meta name=\"format-detection\" content=\"telephone=no,email=no\" />\n```\n\n\n## 附注\n\n部分`meta`定义来自于[trip](https://github.com/doyoe/trip)","slug":"mobile/移动前端第二弹:善用meta","published":1,"updated":"2016-02-22T09:00:09.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvafq00032ypka7qu3u8h"},{"title":"移动前端第一弹:viewport详解","date":"2015-10-13T05:00:11.000Z","author":"杜瑶","_content":"\n## 前言\n\n这次想聊聊移动开发相关的事。是的,你没有看错,一句话就可以开始你的移动前端开发。\n\n你心里一定在想,什么话这么酷,能够瞬间带入到移动前端开发的世界。\n\n但其实它一点也不新奇,不复杂。\n\n## viewport简介\n\n没错,就是`viewport`特性,一个移动专属的`Meta`值,用于定义视口的各种行为。\n\n该特性最先由`Apple`引入,用于解决移动端的页面展示问题,后续被越来越多的厂商跟进。\n\n举个简单的例子来讲为什么会需要它:\n\n我们知道用户大规模使用手机等移动设备来进行网页浏览器,其实得益于智能手持设备的兴起,也就是近几年的事。(还记得不久前的几年,满大街都还是诺基亚的天下么?)\n\n这时有一个很现实的问题摆在了厂商面前,用户并不能很好地通过手机等设备访问网页,因为屏幕太小。\n\n<!--more-->\n\n### layout viewport\n\n`Apple`也发现了这个问题,并且适时的出现,它提出了一个方案用来解决这个问题。在iOS Safari中定义了一个`viewport meta`标签,用来创建一个虚拟的`布局视口(layout viewport)`,而这个视口的分辨率接近于PC显示器,`Apple`将其定义为`980px`(其他厂商各有不同①)。\n\n这就很好的解决了早期的页面在手机上显示的问题,由于两者之间的宽度趋近,CSS只需要像在PC上那样渲染页面就行,原有的页面结构不会被破坏。\n\n> ①的描述大致如下,数值不一定持续准确,厂商可能更改,但这个绝对值其实并非特别重要:\n> iOS, Android基本都是: 980px\n> BlackBerry: 1024px\n\n### visual viewport\n\n有了`layout viewport`,我们还需要一个视口用来承载它,这个视口可以简单的认为是手持设备物理屏幕的可视区域,我们称之为`(视觉视口)visual viewport`。这是一个比较直观的概念,因为你能看得见你的手机屏幕。\n\n对于`visual viewport`,开发者一般只需要知道它的存在和概念就行,因为无法对它进行任何设置或者修改。很明显,`visual viewport`的尺寸不会是一个固定的值,甚至每款设备都可能不同。大致列几种常见设备的`visual viewport`尺寸:\n\n* iPhone4~iPhone5S: 320*480px\n* iPhone6~iPhone6S: 375*627px\n* iPhone6 Plus~iPhone6S Plus: 414*736px\n\n以`iPhone4S`为例,会在其320px②的`visual viewport`上,创建一个宽`980px`的`layout viewport`,于是用户可以在`visual viewport`中拖动或者缩放网页,来获得良好的浏览效果;布局视口用来配合CSS渲染布局,当我们定义一个容器的宽度为`100%`时,这个容器的实际宽度是`980px`而不是`320px`,通过这种方式大部分网页就能以缩放的形式正常显示在手机屏幕上了。\n\n> ②的描述大致如下:\n> 早期移动前端开发工程师常能见到宽640px的设计稿,原因就是UI工程师以物理屏幕宽度为320px的`iPhone4-iPhone5S`作为参照设计;\n> 当然,现在你还可能会见到750px和1242px尺寸的设计稿,原因当然是iPhone6的出现\n\n当然,为了更好的适配移动端或者只为移动端设计的应用,单有布局视口和视觉视口还是不够的。\n\n### ideal viewport\n\n我们还需要一个视口,它类似于布局视口,但宽度和视觉视口相同,这就是完美视口(ideal viewport)。\n\n有了完美视口,用户不用缩放和拖动网页就能够很好的进行网页浏览。而完美视口也是通过`viewport meta`的某种设置来达到。\n\n说了这么一大堆的东西,貌似都和`viewport`有关联,那么`viewport`到底怎么搞,请继续往下。\n\n> 关于3个视口,[PPK](http://www.quirksmode.org/)已经做了非常棒的阐释,你也可以在`StackOverflow`上找到一些对此描述的相互补充,例如:[[1]](http://stackoverflow.com/questions/6333927/difference-between-visual-viewport-and-layout-viewport), [[2]](http://stackoverflow.com/questions/7344886/visual-viewport-vs-layout-viewport-on-mobile-devices),有兴趣的童鞋也可以看看\n\n## viewport特性\n\n通常情况下,`viewport`有以下6种设置。当然厂商可能会增加一些特定的设置,比如iOS Safari7.1增加了一种在网页加载时隐藏地址栏与导航栏的设置:`minimal-ui`,不过随后又将之移除了。\n\nName|Value|Description\n---|---|\nwidth|正整数或`device-width`|定义视口的宽度,单位为像素\nheight|正整数或`device-height`|定义视口的高度,单位为像素\ninitial-scale|[0.0-10.0]|定义初始缩放值\nminimum-scale|[0.0-10.0]|定义缩小最小比例,它必须小于或等于maximum-scale设置\nmaximum-scale|[0.0-10.0]|定义放大最大比例,它必须大于或等于minimum-scale设置\nuser-scalable|yes/no|定义是否允许用户手动缩放页面,默认值yes\n\n### width\n\n`width`被用来定义`layout viewport`的宽度,如果不指定该属性(或者移除`viewport meta`标签),则`layout viewport`宽度为厂商默认值。如:iPhone为`980px`;\n\n举个例子:\n\n```\n<meta name=\"viewport\" content=\"width=device-width\" />\n```\n\n此时的`layout viewport`将成为`ideal viewport`,因为`layout viewport`宽度与设备视觉视口宽度一致了。\n\n除了`width`之外,还有一个属性定义也能实现`ideal viewport`,那就是`initial-scale`。\n\n### height\n\n与`width`类似,但实际上却不常用,因为没有太多的use case。\n\n### initial-scale\n\n如果想页面默认以某个比例放大或者缩小然后呈现给用户,那么可以通过定义`initial-scale`来完成。\n\n`initial-scale`用于指定页面的初始缩放比例,假定你这样定义:\n\n```\n<meta name=\"viewport\" content=\"initial-scale=2\" />\n```\n\n那么用户将会看到2倍大小的页面内容。\n\n在说`width`的时候,我们说到`initial-scale`也能实现`ideal viewport`,是的,你只需要这样做,也可以得到完美视口:\n\n```\n<meta name=\"viewport\" content=\"initial-scale=1\" />\n```\n\n### maximum-scale\n\n在移动端,你可能会考虑用户浏览不便,然后给予用户放大页面的权利,但同时又希望是在一定范围内的放大,这时就可以使用`maximum-scale`来进行约束。\n\n`maximum-scale`用于指定用户能够放大的比例。\n\n举个例子来讲:\n\n```\n<meta name=\"viewport\" content=\"initial-scale=1,maximum-scale=5\" />\n```\n\n假设页面的默认缩放值`initial-scale`是`1`,那么用户最终能够将页面放大到这个初始页面大小的5倍。\n\n### minimum-scale\n\n类似`maximum-scale`的描述,不过`minimum-scale`是用来指定页面缩小比例的。\n\n通常情况下,为了有更好地体验,不会定义该属性的值比`1`更小,因为那样页面将变得难以阅读。\n\n### user-scalable\n\n如果你不想页面被放大或者缩小,通过定义`user-scalable`来约束用户是否可以通过手势对页面进行缩放即可。\n\n该属性的默认值为`yes`,即可被缩放(如果使用默认值,该属性可以不定义);当然,如果你的应用不打算让用户拥有缩放权限,可以将该值设置为`no`。\n\n使用方法如下:\n\n```\n<meta name=\"viewport\" content=\"user-scalable=no\" />\n```\n\n## 结语\n\n正如开篇所说,这既不高深也不新奇,它而仅仅是一点观念转变。\n\n当你掌握了`viewport`,那么意味着你已经大致了解了移动平台与PC平台的不同,你可以更专注而细致的去解决某些平台差异问题。","source":"_posts/mobile/移动前端第一弹:viewport详解.md","raw":"title: 移动前端第一弹:viewport详解\ndate: 2015-10-13 13:00:11\nauthor: 杜瑶\ncategories: mobile\ntags: [HTML5, viewport, meta]\n---\n\n## 前言\n\n这次想聊聊移动开发相关的事。是的,你没有看错,一句话就可以开始你的移动前端开发。\n\n你心里一定在想,什么话这么酷,能够瞬间带入到移动前端开发的世界。\n\n但其实它一点也不新奇,不复杂。\n\n## viewport简介\n\n没错,就是`viewport`特性,一个移动专属的`Meta`值,用于定义视口的各种行为。\n\n该特性最先由`Apple`引入,用于解决移动端的页面展示问题,后续被越来越多的厂商跟进。\n\n举个简单的例子来讲为什么会需要它:\n\n我们知道用户大规模使用手机等移动设备来进行网页浏览器,其实得益于智能手持设备的兴起,也就是近几年的事。(还记得不久前的几年,满大街都还是诺基亚的天下么?)\n\n这时有一个很现实的问题摆在了厂商面前,用户并不能很好地通过手机等设备访问网页,因为屏幕太小。\n\n<!--more-->\n\n### layout viewport\n\n`Apple`也发现了这个问题,并且适时的出现,它提出了一个方案用来解决这个问题。在iOS Safari中定义了一个`viewport meta`标签,用来创建一个虚拟的`布局视口(layout viewport)`,而这个视口的分辨率接近于PC显示器,`Apple`将其定义为`980px`(其他厂商各有不同①)。\n\n这就很好的解决了早期的页面在手机上显示的问题,由于两者之间的宽度趋近,CSS只需要像在PC上那样渲染页面就行,原有的页面结构不会被破坏。\n\n> ①的描述大致如下,数值不一定持续准确,厂商可能更改,但这个绝对值其实并非特别重要:\n> iOS, Android基本都是: 980px\n> BlackBerry: 1024px\n\n### visual viewport\n\n有了`layout viewport`,我们还需要一个视口用来承载它,这个视口可以简单的认为是手持设备物理屏幕的可视区域,我们称之为`(视觉视口)visual viewport`。这是一个比较直观的概念,因为你能看得见你的手机屏幕。\n\n对于`visual viewport`,开发者一般只需要知道它的存在和概念就行,因为无法对它进行任何设置或者修改。很明显,`visual viewport`的尺寸不会是一个固定的值,甚至每款设备都可能不同。大致列几种常见设备的`visual viewport`尺寸:\n\n* iPhone4~iPhone5S: 320*480px\n* iPhone6~iPhone6S: 375*627px\n* iPhone6 Plus~iPhone6S Plus: 414*736px\n\n以`iPhone4S`为例,会在其320px②的`visual viewport`上,创建一个宽`980px`的`layout viewport`,于是用户可以在`visual viewport`中拖动或者缩放网页,来获得良好的浏览效果;布局视口用来配合CSS渲染布局,当我们定义一个容器的宽度为`100%`时,这个容器的实际宽度是`980px`而不是`320px`,通过这种方式大部分网页就能以缩放的形式正常显示在手机屏幕上了。\n\n> ②的描述大致如下:\n> 早期移动前端开发工程师常能见到宽640px的设计稿,原因就是UI工程师以物理屏幕宽度为320px的`iPhone4-iPhone5S`作为参照设计;\n> 当然,现在你还可能会见到750px和1242px尺寸的设计稿,原因当然是iPhone6的出现\n\n当然,为了更好的适配移动端或者只为移动端设计的应用,单有布局视口和视觉视口还是不够的。\n\n### ideal viewport\n\n我们还需要一个视口,它类似于布局视口,但宽度和视觉视口相同,这就是完美视口(ideal viewport)。\n\n有了完美视口,用户不用缩放和拖动网页就能够很好的进行网页浏览。而完美视口也是通过`viewport meta`的某种设置来达到。\n\n说了这么一大堆的东西,貌似都和`viewport`有关联,那么`viewport`到底怎么搞,请继续往下。\n\n> 关于3个视口,[PPK](http://www.quirksmode.org/)已经做了非常棒的阐释,你也可以在`StackOverflow`上找到一些对此描述的相互补充,例如:[[1]](http://stackoverflow.com/questions/6333927/difference-between-visual-viewport-and-layout-viewport), [[2]](http://stackoverflow.com/questions/7344886/visual-viewport-vs-layout-viewport-on-mobile-devices),有兴趣的童鞋也可以看看\n\n## viewport特性\n\n通常情况下,`viewport`有以下6种设置。当然厂商可能会增加一些特定的设置,比如iOS Safari7.1增加了一种在网页加载时隐藏地址栏与导航栏的设置:`minimal-ui`,不过随后又将之移除了。\n\nName|Value|Description\n---|---|\nwidth|正整数或`device-width`|定义视口的宽度,单位为像素\nheight|正整数或`device-height`|定义视口的高度,单位为像素\ninitial-scale|[0.0-10.0]|定义初始缩放值\nminimum-scale|[0.0-10.0]|定义缩小最小比例,它必须小于或等于maximum-scale设置\nmaximum-scale|[0.0-10.0]|定义放大最大比例,它必须大于或等于minimum-scale设置\nuser-scalable|yes/no|定义是否允许用户手动缩放页面,默认值yes\n\n### width\n\n`width`被用来定义`layout viewport`的宽度,如果不指定该属性(或者移除`viewport meta`标签),则`layout viewport`宽度为厂商默认值。如:iPhone为`980px`;\n\n举个例子:\n\n```\n<meta name=\"viewport\" content=\"width=device-width\" />\n```\n\n此时的`layout viewport`将成为`ideal viewport`,因为`layout viewport`宽度与设备视觉视口宽度一致了。\n\n除了`width`之外,还有一个属性定义也能实现`ideal viewport`,那就是`initial-scale`。\n\n### height\n\n与`width`类似,但实际上却不常用,因为没有太多的use case。\n\n### initial-scale\n\n如果想页面默认以某个比例放大或者缩小然后呈现给用户,那么可以通过定义`initial-scale`来完成。\n\n`initial-scale`用于指定页面的初始缩放比例,假定你这样定义:\n\n```\n<meta name=\"viewport\" content=\"initial-scale=2\" />\n```\n\n那么用户将会看到2倍大小的页面内容。\n\n在说`width`的时候,我们说到`initial-scale`也能实现`ideal viewport`,是的,你只需要这样做,也可以得到完美视口:\n\n```\n<meta name=\"viewport\" content=\"initial-scale=1\" />\n```\n\n### maximum-scale\n\n在移动端,你可能会考虑用户浏览不便,然后给予用户放大页面的权利,但同时又希望是在一定范围内的放大,这时就可以使用`maximum-scale`来进行约束。\n\n`maximum-scale`用于指定用户能够放大的比例。\n\n举个例子来讲:\n\n```\n<meta name=\"viewport\" content=\"initial-scale=1,maximum-scale=5\" />\n```\n\n假设页面的默认缩放值`initial-scale`是`1`,那么用户最终能够将页面放大到这个初始页面大小的5倍。\n\n### minimum-scale\n\n类似`maximum-scale`的描述,不过`minimum-scale`是用来指定页面缩小比例的。\n\n通常情况下,为了有更好地体验,不会定义该属性的值比`1`更小,因为那样页面将变得难以阅读。\n\n### user-scalable\n\n如果你不想页面被放大或者缩小,通过定义`user-scalable`来约束用户是否可以通过手势对页面进行缩放即可。\n\n该属性的默认值为`yes`,即可被缩放(如果使用默认值,该属性可以不定义);当然,如果你的应用不打算让用户拥有缩放权限,可以将该值设置为`no`。\n\n使用方法如下:\n\n```\n<meta name=\"viewport\" content=\"user-scalable=no\" />\n```\n\n## 结语\n\n正如开篇所说,这既不高深也不新奇,它而仅仅是一点观念转变。\n\n当你掌握了`viewport`,那么意味着你已经大致了解了移动平台与PC平台的不同,你可以更专注而细致的去解决某些平台差异问题。","slug":"mobile/移动前端第一弹:viewport详解","published":1,"updated":"2015-10-19T10:33:32.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvafy000e2ypk2aar6u68"},{"title":"一年又要过去了","date":"2013-11-28T03:15:00.000Z","author":"杜瑶","_content":"\n##\n\n不知不觉,一年又要过去了。这是年龄暴增的节奏啊,以后是不能过青年节了么?次奥!","source":"_posts/life/一年又要过去了.md","raw":"title: 一年又要过去了\ndate: 2013-11-28 11:15:00\ncategories: life\nauthor: 杜瑶\ntags: [随笔, 生活]\n---\n\n##\n\n不知不觉,一年又要过去了。这是年龄暴增的节奏啊,以后是不能过青年节了么?次奥!","slug":"life/一年又要过去了","published":1,"updated":"2016-03-29T02:41:10.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvag1000k2ypks1ixuept"},{"title":"视觉格式化模型中的各种框","date":"2015-03-09T09:29:00.000Z","author":"杜瑶","_content":"\n在聊这个话题之前,我们可能得先简单说说 `视觉格式化模型` 这个概念。\n\n`视觉格式化模型` 的全称是 `Visual formatting model`,它被用来描述用户代理(比如浏览器)在图形媒体下如何处理文档树。\n\n在 `视觉格式化模型` 中,每个文档树的元素会根据[框模型](http://www.w3.org/TR/CSS2/box.html)产生零到多个框(boxes)。这些框的布局取决于框的尺寸,类型,定位方式(正常流,浮动和绝对定位),元素之间的关系和外部信息(例如:视口 ① 大小,置换元素的固有尺寸等等)。\n\n> 举个最简单的例子来讲,假设一个页面上有2个div,那么第2个div的位置会取决第1个div的高度定义;假设更复杂一点,第1个div是浮动的,那么第2个div的位置还要取决于第1个div的宽度。\n\n## 不同类型的框\n\n在 `CSS` 中,可能会产生不同类型的框,框的类型取决于 `display` 属性的设定。某种程度上,框的类型会影响其在视觉格式化模型中的表现。接下来会详细的聊聊这些不同类型的框以及它们在视觉可视化模型中的表现。\n\n在说这个之前,我们先回忆一下,大家常说的一些名词:\n\n<!--more-->\n\n* [Containing block(包含块)](#containing-block)\n* [Block-level element(块级元素)](#block-level-element)\n* [Block element(块元素)](#block-element)\n* [Block-level box(块级框), Block container box(块容器框), Block box(块框)](#block-boxes)\n* [Inline-level element(行内级元素)](#inline-level-element)\n* [Inline element(行内元素)](#inline-element)\n* [Inline-level box(行内级框), Atomic inline-level box(原子行内级框), Inline box(行内框)](#inline-boxes)\n* [Anonymous boxes(匿名框)](#anonymous-boxes)\n\n<a name=\"containing-block\"></a>\n## 包含块\n\n首先,来看看什么是 `包含块`?这个说及 `CSS` 一般的都会提及的基本概念。\n\n一个元素,它的框的尺寸和位置会相对于一个特定的矩形框边缘来计算而得到,这个特定的矩形框称之为该元素的 `包含块`。\n\n(为)一个元素生成的框通常会充当其子框的包含块;当我们叫一个 `框的包含块` 时,其实表达的是 `该框所处的包含块`,而不是其自身产生的包含块。\n\n每个框相对于其包含块(`该框所处的包含块`)都会被给予一个位置,不过该框并不局限在包含块内,有可能会溢出,通常这个时候你会借助 `overflow` 属性来进行处理。\n\n除了说什么是包含块,这里顺带再介绍一下生成包含块的一些特殊场景:\n\n* 由根元素生成的包含块叫做 `初始包含块(initial containing block)`。\n* 对于其它元素,如果元素的 `position` 值是 `relative` 或者 `static`,其包含块由最近的祖先 `块容器框` 的内容边界(如果想知道什么是内容边界,可以先看看CSS盒模型)形成。\n> 举个例子,`td`, `th` 就算有父容器 `tr`,但它们的包含块却是由 `table` 生成,因为 `table` 是 `块容器框` 而 `tr` 不是\n\n* 绝对定位元素的包含块由最近的定位(`position` 值非 `static`)祖先生成,如果不存在这样的祖先,则采用初始包含块;\n* 固定定位元素(`position: fixed`)的包含块一般情况下都由视口 ① 生成;\n\n说了这几个特殊的情景,你会发现并不是所有的包含块都是由父元素所生成。\n\n<a name=\"block-level-element\"></a>\n## 什么是块级元素?\n\n块级元素是那些视觉上会被格式化成块状的元素,通俗一点来说就是那些会换新行的元素。`display` 属性的:`block`, `list-item`, `table`, `flex`, `grid` 值都可以将一个元素设置成块级元素。\n\n> 举个例子来说,`li` 是一个 `块级元素`,但也有人会说它是一个 `块元素`。嗯,`li` 确实是一个块级元素,但并不是一个块元素,为什么?\n\n<a name=\"block-element\"></a>\n## 什么是块元素?\n\n块元素是 `display` 属性值为 `block` 的元素,它应该是 `块级元素` 的一个子集,而不是等同的,一个 `块元素` 是一个 `块级元素`,但一个 `块级元素` 不一定是一个 `块元素`,所以不要混淆。\n\n<a name=\"block-boxes\"></a>\n## 块级框,块容器框,块框\n\n### 什么是块级框?\n\n块级元素生成块级框,这些框会参与某些 `BFC`。每个块级元素都会生成一个主要的块级框来包含其子框和生成的内容,同时任何定位方式都会与这个主要的块级框有关。\n\n某些块级元素还会在主要的块级框之外产生额外的框:例如 `list-item` 元素,它需要生成一个额外的框用于包含 `list-style-type`。这些额外的框会相对于主要的块级框来进行排版。\n\n### 什么是块容器框?\n\n一个 `块容器框` 要么只包含 `块级框`,要么创建一个 `IFC` 而只包含 `行内级框`,但不能同时包含 `块级框` 和 `行内级框`。\n\n除了 `table框` 和 `置换元素`,一个 `块级框` 同时也是一个 `块容器框`。`非置换的行内块` 和 `单元格` 是 `块容器` 但不是 `块级框`。\n\n并不是所有的 `块级框` 都是 `块容器框`,也并不是所有的 `块容器框` 都是 `块级框`。\n\n`块级框` 和 `块容器框` 的另外一个重要的区别是:`块级框` 需要能够包含其生成的内容,但 `块容器框` 并不需要。这是什么意思呢?简单的解释一下:\n\n> 比如一个 `iframe` 其内容由 `src` 属性所决定,这可以当成是生成的内容,所以 `iframe` 是一个 `块级框` 但却不是 `块容器框`\n\n### 什么是块框?\n\n简要的来说,是 `块容器` 的 `块级框` 称之为 `块框`。\n\n可以通过下面这个图来快速的梳理清楚这3者之间的联系:\n\n![block boxes](../../../../../image/boxes/block-boxes.png)(图一)\n\n说完了块级框,接下来说说行内级框\n\n<a name=\"inline-level-element\"></a>\n## 什么是行内级元素?\n\n行内级元素是那些不会为自身内容形成新的块,而让内容分布在多行中的元素。`display` 属性的:`inline`, `inline-table`, `inline-block`, `inline-flex`, `inline-grid` 值都可以将一个元素设置成行内级元素。\n\n<a name=\"inline-element\"></a>\n## 什么是行内元素?\n\n如同块元素之于块级元素的关系,行内元素仅仅是 `display` 属性值为 `inline` 的元素,这里不再赘述。\n\n<a name=\"inline-boxes\"></a>\n## 行内级框,原子行内级框,行内框\n\n行内级元素生成行内级框,而这些框会参与某个 `IFC`。一个 `行内框` 是 `行内级框`,且其内容参与了包含它的 `IFC`。一个 `display` 值是 `inline` 的非置换元素会生成一个行内框。那些不是行内框的行内级框(例如行内级置换元素、行内块元素、行内表格元素)被称为 `原子行内级框`,因为它们是以单一不透明框的形式来参与其 `IFC` 的。\n\n细心的你会发现并没有一个 `行内容器框` 与 `块容器框` 相对应,但却多了一个 `原子行内级框`。并且有趣的是`行内块`(包括置换和非置换元素)是`原子行内级框`,而`非置换行内块`却同时还是`块容器框`。\n\n![inline boxes](../../../../../image/boxes/inline-boxes.png)(图二)\n\n<a name=\"anonymous-boxes\"></a>\n## 匿名框\n\n`匿名框` 包括 `匿名块框` 和 `匿名行内框`。\n\n假设一个 `div` 中包含有一个 `p` 和一段纯文本 `xxx`。由于 `块容器框` 只允许要么包含 `块级框`,要么包含 `行内级框`,所以,为了符合这种情况,`div` 会生成一个匿名的块级框用于包裹 `xxx`,这个匿名框就叫做 `匿名块框`。\n\n我们拿 `W3C` 上的一个例子来加深对匿名块框的印象:\n\n```\n<div>\n Some text\n <p>More text</p>\n</div>\n```\n\n![Anonymous block boxes](http://www.w3.org/TR/CSS2/images/anon-block.png)(图三)\n\n与此同时,我们将上面的代码稍微改一下,将 `p` 变成 `span`:\n\n```\n<div>\n Some text\n <span>More text</span>\n</div>\n```\n\n`div` 生成一个块框,`More text` 由 `span` 生成一个行内框,由于 `Some text` 没有与之相关的行级元素,将由 `div` 为其生成一个行内框用以包裹,这个框称为匿名行内框。如图四:\n\n![Anonymous block boxes](../../../../../image/boxes/anon-inline.png)(图四)\n\n假设一个匿名框的类型可根据上下文来清晰界定,则 `匿名行内框` 和 `匿名块框` 都可被简称为 `匿名框`。\n\n匿名框的继承属性会从包含它的非匿名框那里继承,非继承属性取其初始值。\n\n## 附注:\n\n* ① 用户代理一般会向用户提供一个载体(屏幕上的一个窗口或其它可视区域)用以访问文档,这个载体就叫做 `视口`。用户代理可以在视口大小被调整时改变文档的布局。如果视口小于渲染文档的画布区域,用户代理应当提供一个滚动机制。每个画布只能拥有一个视口,但用户代理可以把文档渲染至多个画布上(即为相同文档提供不同的视图)。\n\n## 说明:\n\n* 最近的文章都是断断续续写的,如读者朋友发现存在描述错误地方请及时提醒。","source":"_posts/css/视觉格式化模型中的各种框.md","raw":"title: 视觉格式化模型中的各种框\ndate: 2015-03-09 17:29:00\ncategories: CSS\nauthor: 杜瑶\ntags: [w3c, 视觉格式化模型, 包含块]\n---\n\n在聊这个话题之前,我们可能得先简单说说 `视觉格式化模型` 这个概念。\n\n`视觉格式化模型` 的全称是 `Visual formatting model`,它被用来描述用户代理(比如浏览器)在图形媒体下如何处理文档树。\n\n在 `视觉格式化模型` 中,每个文档树的元素会根据[框模型](http://www.w3.org/TR/CSS2/box.html)产生零到多个框(boxes)。这些框的布局取决于框的尺寸,类型,定位方式(正常流,浮动和绝对定位),元素之间的关系和外部信息(例如:视口 ① 大小,置换元素的固有尺寸等等)。\n\n> 举个最简单的例子来讲,假设一个页面上有2个div,那么第2个div的位置会取决第1个div的高度定义;假设更复杂一点,第1个div是浮动的,那么第2个div的位置还要取决于第1个div的宽度。\n\n## 不同类型的框\n\n在 `CSS` 中,可能会产生不同类型的框,框的类型取决于 `display` 属性的设定。某种程度上,框的类型会影响其在视觉格式化模型中的表现。接下来会详细的聊聊这些不同类型的框以及它们在视觉可视化模型中的表现。\n\n在说这个之前,我们先回忆一下,大家常说的一些名词:\n\n<!--more-->\n\n* [Containing block(包含块)](#containing-block)\n* [Block-level element(块级元素)](#block-level-element)\n* [Block element(块元素)](#block-element)\n* [Block-level box(块级框), Block container box(块容器框), Block box(块框)](#block-boxes)\n* [Inline-level element(行内级元素)](#inline-level-element)\n* [Inline element(行内元素)](#inline-element)\n* [Inline-level box(行内级框), Atomic inline-level box(原子行内级框), Inline box(行内框)](#inline-boxes)\n* [Anonymous boxes(匿名框)](#anonymous-boxes)\n\n<a name=\"containing-block\"></a>\n## 包含块\n\n首先,来看看什么是 `包含块`?这个说及 `CSS` 一般的都会提及的基本概念。\n\n一个元素,它的框的尺寸和位置会相对于一个特定的矩形框边缘来计算而得到,这个特定的矩形框称之为该元素的 `包含块`。\n\n(为)一个元素生成的框通常会充当其子框的包含块;当我们叫一个 `框的包含块` 时,其实表达的是 `该框所处的包含块`,而不是其自身产生的包含块。\n\n每个框相对于其包含块(`该框所处的包含块`)都会被给予一个位置,不过该框并不局限在包含块内,有可能会溢出,通常这个时候你会借助 `overflow` 属性来进行处理。\n\n除了说什么是包含块,这里顺带再介绍一下生成包含块的一些特殊场景:\n\n* 由根元素生成的包含块叫做 `初始包含块(initial containing block)`。\n* 对于其它元素,如果元素的 `position` 值是 `relative` 或者 `static`,其包含块由最近的祖先 `块容器框` 的内容边界(如果想知道什么是内容边界,可以先看看CSS盒模型)形成。\n> 举个例子,`td`, `th` 就算有父容器 `tr`,但它们的包含块却是由 `table` 生成,因为 `table` 是 `块容器框` 而 `tr` 不是\n\n* 绝对定位元素的包含块由最近的定位(`position` 值非 `static`)祖先生成,如果不存在这样的祖先,则采用初始包含块;\n* 固定定位元素(`position: fixed`)的包含块一般情况下都由视口 ① 生成;\n\n说了这几个特殊的情景,你会发现并不是所有的包含块都是由父元素所生成。\n\n<a name=\"block-level-element\"></a>\n## 什么是块级元素?\n\n块级元素是那些视觉上会被格式化成块状的元素,通俗一点来说就是那些会换新行的元素。`display` 属性的:`block`, `list-item`, `table`, `flex`, `grid` 值都可以将一个元素设置成块级元素。\n\n> 举个例子来说,`li` 是一个 `块级元素`,但也有人会说它是一个 `块元素`。嗯,`li` 确实是一个块级元素,但并不是一个块元素,为什么?\n\n<a name=\"block-element\"></a>\n## 什么是块元素?\n\n块元素是 `display` 属性值为 `block` 的元素,它应该是 `块级元素` 的一个子集,而不是等同的,一个 `块元素` 是一个 `块级元素`,但一个 `块级元素` 不一定是一个 `块元素`,所以不要混淆。\n\n<a name=\"block-boxes\"></a>\n## 块级框,块容器框,块框\n\n### 什么是块级框?\n\n块级元素生成块级框,这些框会参与某些 `BFC`。每个块级元素都会生成一个主要的块级框来包含其子框和生成的内容,同时任何定位方式都会与这个主要的块级框有关。\n\n某些块级元素还会在主要的块级框之外产生额外的框:例如 `list-item` 元素,它需要生成一个额外的框用于包含 `list-style-type`。这些额外的框会相对于主要的块级框来进行排版。\n\n### 什么是块容器框?\n\n一个 `块容器框` 要么只包含 `块级框`,要么创建一个 `IFC` 而只包含 `行内级框`,但不能同时包含 `块级框` 和 `行内级框`。\n\n除了 `table框` 和 `置换元素`,一个 `块级框` 同时也是一个 `块容器框`。`非置换的行内块` 和 `单元格` 是 `块容器` 但不是 `块级框`。\n\n并不是所有的 `块级框` 都是 `块容器框`,也并不是所有的 `块容器框` 都是 `块级框`。\n\n`块级框` 和 `块容器框` 的另外一个重要的区别是:`块级框` 需要能够包含其生成的内容,但 `块容器框` 并不需要。这是什么意思呢?简单的解释一下:\n\n> 比如一个 `iframe` 其内容由 `src` 属性所决定,这可以当成是生成的内容,所以 `iframe` 是一个 `块级框` 但却不是 `块容器框`\n\n### 什么是块框?\n\n简要的来说,是 `块容器` 的 `块级框` 称之为 `块框`。\n\n可以通过下面这个图来快速的梳理清楚这3者之间的联系:\n\n![block boxes](../../../../../image/boxes/block-boxes.png)(图一)\n\n说完了块级框,接下来说说行内级框\n\n<a name=\"inline-level-element\"></a>\n## 什么是行内级元素?\n\n行内级元素是那些不会为自身内容形成新的块,而让内容分布在多行中的元素。`display` 属性的:`inline`, `inline-table`, `inline-block`, `inline-flex`, `inline-grid` 值都可以将一个元素设置成行内级元素。\n\n<a name=\"inline-element\"></a>\n## 什么是行内元素?\n\n如同块元素之于块级元素的关系,行内元素仅仅是 `display` 属性值为 `inline` 的元素,这里不再赘述。\n\n<a name=\"inline-boxes\"></a>\n## 行内级框,原子行内级框,行内框\n\n行内级元素生成行内级框,而这些框会参与某个 `IFC`。一个 `行内框` 是 `行内级框`,且其内容参与了包含它的 `IFC`。一个 `display` 值是 `inline` 的非置换元素会生成一个行内框。那些不是行内框的行内级框(例如行内级置换元素、行内块元素、行内表格元素)被称为 `原子行内级框`,因为它们是以单一不透明框的形式来参与其 `IFC` 的。\n\n细心的你会发现并没有一个 `行内容器框` 与 `块容器框` 相对应,但却多了一个 `原子行内级框`。并且有趣的是`行内块`(包括置换和非置换元素)是`原子行内级框`,而`非置换行内块`却同时还是`块容器框`。\n\n![inline boxes](../../../../../image/boxes/inline-boxes.png)(图二)\n\n<a name=\"anonymous-boxes\"></a>\n## 匿名框\n\n`匿名框` 包括 `匿名块框` 和 `匿名行内框`。\n\n假设一个 `div` 中包含有一个 `p` 和一段纯文本 `xxx`。由于 `块容器框` 只允许要么包含 `块级框`,要么包含 `行内级框`,所以,为了符合这种情况,`div` 会生成一个匿名的块级框用于包裹 `xxx`,这个匿名框就叫做 `匿名块框`。\n\n我们拿 `W3C` 上的一个例子来加深对匿名块框的印象:\n\n```\n<div>\n Some text\n <p>More text</p>\n</div>\n```\n\n![Anonymous block boxes](http://www.w3.org/TR/CSS2/images/anon-block.png)(图三)\n\n与此同时,我们将上面的代码稍微改一下,将 `p` 变成 `span`:\n\n```\n<div>\n Some text\n <span>More text</span>\n</div>\n```\n\n`div` 生成一个块框,`More text` 由 `span` 生成一个行内框,由于 `Some text` 没有与之相关的行级元素,将由 `div` 为其生成一个行内框用以包裹,这个框称为匿名行内框。如图四:\n\n![Anonymous block boxes](../../../../../image/boxes/anon-inline.png)(图四)\n\n假设一个匿名框的类型可根据上下文来清晰界定,则 `匿名行内框` 和 `匿名块框` 都可被简称为 `匿名框`。\n\n匿名框的继承属性会从包含它的非匿名框那里继承,非继承属性取其初始值。\n\n## 附注:\n\n* ① 用户代理一般会向用户提供一个载体(屏幕上的一个窗口或其它可视区域)用以访问文档,这个载体就叫做 `视口`。用户代理可以在视口大小被调整时改变文档的布局。如果视口小于渲染文档的画布区域,用户代理应当提供一个滚动机制。每个画布只能拥有一个视口,但用户代理可以把文档渲染至多个画布上(即为相同文档提供不同的视图)。\n\n## 说明:\n\n* 最近的文章都是断断续续写的,如读者朋友发现存在描述错误地方请及时提醒。","slug":"css/视觉格式化模型中的各种框","published":1,"updated":"2016-03-29T02:40:47.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvag5000r2ypkt9h8j2de"},{"title":"置换和非置换元素","date":"2015-03-15T05:16:00.000Z","author":"杜瑶","_content":"\n## 先进一个题外话\n\n在面试一个 `重构`(各大公司的叫法可能不太一样)时,我喜欢从一个点开始问,然后一直延展下去成为一条线,甚至是一个面,直到问到不会的地方,然后又换另外一个点。\n\n> 例如:我可能会说,能简单聊聊 `行内级元素` 和 `块级元素` 的区别吗。\n\n一般这时,候选人都会说到 `行内级元素` 不会换新行,而 `块级元素` 会格式化为块状,即换行。但也有些遗憾的方面(如:[混淆了块元素和块级元素,行内元素和行内级元素](/2015/03/09/css/视觉格式化模型中的各种框/#block-level-element)),当然这看起来似乎不是特别重要。\n\n> 这时我会继续问,`行内元素` 能够定义宽度和高度吗?\n\n不少候选人会说:**不能**\n\n> 我会继续问,说几个你熟悉的 `行内元素` 吧\n\n于是 `span`, `strong`, `em`, `ins`... 答案我还是比较满意的。\n\n> 我仍然会继续,`img` 是行内元素么?\n\n候选人这时通常会迟疑一下,可能意识到我接下来想问啥了,但还是会回答:**是**\n\n<!--more-->\n\n> 于是我会说,那 `img` 能定义宽度和高度么?\n\n有的候选人这时会犹豫,因为如果回答是,就会推翻他之前说的 `行内元素不能定义宽高`,如果回答不是,似乎又和他所熟知的经验不一致。但通常最后还是会回答:**能**\n\n> 那我就又得问,你之前不是说 `行内元素不能定义宽高` 吗?为什么 `img` 可以?\n\n到这里,候选人基本上不知道要怎么回答好了,最后可能会告诉我,**因为 `img` 是特殊元素**\n\n当然,虽然这么回答也不能说是错误的,但基本上也能知道候选人对这条线的基础的掌握程度了。\n\n但我希望听到的答案是通过解释置换元素相关的概念从而给出答案。\n\n## 什么是置换元素?\n\n一个 `内容` 不受CSS视觉格式化模型控制,CSS渲染模型并不考虑对此内容的渲染,且元素本身一般拥有固有尺寸(宽度,高度,宽高比)的元素,被称之为置换元素。\n\n## 什么是非置换元素?\n\nw3c并没有给出明确的非置换元素的解释,但能确定的是除置换元素之外,所有的元素都是非置换元素。\n\n## 行内级置换和非置换元素的宽度定义\n\n对于行内级非置换元素,宽度设置是不适用的。\n\n对于行内级置换元素来说,其宽度的设置需遵循以下几点:\n\n* 若宽高的计算值都为 `auto` 且元素有固有宽度,则 `width` 的使用值为该固有宽度;\n> 典型的例子是:拥有默认宽高的 `input` 当宽度的计算值为auto时,则宽度使用值为其默认的固有宽度\n* 若宽度的计算值为 `auto` 且元素有固有宽度,则 `width` 的使用值为该固有宽度;\n> 例子同上\n* 若宽度的计算值为 `auto` 且高度有 `非auto` 的计算值,并且元素有固有宽高比,则 `width` 的使用值为 `高度使用值 * 固有宽高比`;\n> 典型的例子:`img` 当只定义了其高度值时,其宽度将会根据固有宽高比进行等比设置\n* 除此之外,当 `width` 的计算值为 `auto` 时,则宽度的使用值为 `300px`\n> 典型的例子:比如iframe, canvas\n\n其它类型的置换元素,其宽度的定义都参照行内置换元素的定义。\n\n## 行内级置换和非置换元素的高度定义\n\n对于行内级非置换元素,高度设置是不适用的。\n\n对于行内级置换元素来说,其高度的设置需遵循以下几点:\n\n* 若宽高的计算值都为 `auto` 且元素有固有高度,则 `height` 的使用值为该固有高度;\n* 若高度的计算值为 `auto` 且元素有固有高度,则 `height` 的使用值为该固有高度;\n* 若高度的计算值为 `auto` 且宽度有 `非auto` 的计算值,并且元素有固有宽高比,则 `height` 的使用值为:`宽度使用值 / 固有宽高比`;\n* 若高度的计算值为 `auto` 且上述条件完全不符,则 `height` 的使用值 `不能大于150px`,且宽度不能大于长方形高度的2倍。\n\n其它类型的置换元素,其高度的定义都参照行内置换元素的定义。","source":"_posts/css/置换和非置换元素.md","raw":"title: 置换和非置换元素\ndate: 2015-03-15 13:16:00\ncategories: CSS\nauthor: 杜瑶\ntags: [w3c, 视觉格式化模型, 非置换元素, 置换元素]\n---\n\n## 先进一个题外话\n\n在面试一个 `重构`(各大公司的叫法可能不太一样)时,我喜欢从一个点开始问,然后一直延展下去成为一条线,甚至是一个面,直到问到不会的地方,然后又换另外一个点。\n\n> 例如:我可能会说,能简单聊聊 `行内级元素` 和 `块级元素` 的区别吗。\n\n一般这时,候选人都会说到 `行内级元素` 不会换新行,而 `块级元素` 会格式化为块状,即换行。但也有些遗憾的方面(如:[混淆了块元素和块级元素,行内元素和行内级元素](/2015/03/09/css/视觉格式化模型中的各种框/#block-level-element)),当然这看起来似乎不是特别重要。\n\n> 这时我会继续问,`行内元素` 能够定义宽度和高度吗?\n\n不少候选人会说:**不能**\n\n> 我会继续问,说几个你熟悉的 `行内元素` 吧\n\n于是 `span`, `strong`, `em`, `ins`... 答案我还是比较满意的。\n\n> 我仍然会继续,`img` 是行内元素么?\n\n候选人这时通常会迟疑一下,可能意识到我接下来想问啥了,但还是会回答:**是**\n\n<!--more-->\n\n> 于是我会说,那 `img` 能定义宽度和高度么?\n\n有的候选人这时会犹豫,因为如果回答是,就会推翻他之前说的 `行内元素不能定义宽高`,如果回答不是,似乎又和他所熟知的经验不一致。但通常最后还是会回答:**能**\n\n> 那我就又得问,你之前不是说 `行内元素不能定义宽高` 吗?为什么 `img` 可以?\n\n到这里,候选人基本上不知道要怎么回答好了,最后可能会告诉我,**因为 `img` 是特殊元素**\n\n当然,虽然这么回答也不能说是错误的,但基本上也能知道候选人对这条线的基础的掌握程度了。\n\n但我希望听到的答案是通过解释置换元素相关的概念从而给出答案。\n\n## 什么是置换元素?\n\n一个 `内容` 不受CSS视觉格式化模型控制,CSS渲染模型并不考虑对此内容的渲染,且元素本身一般拥有固有尺寸(宽度,高度,宽高比)的元素,被称之为置换元素。\n\n## 什么是非置换元素?\n\nw3c并没有给出明确的非置换元素的解释,但能确定的是除置换元素之外,所有的元素都是非置换元素。\n\n## 行内级置换和非置换元素的宽度定义\n\n对于行内级非置换元素,宽度设置是不适用的。\n\n对于行内级置换元素来说,其宽度的设置需遵循以下几点:\n\n* 若宽高的计算值都为 `auto` 且元素有固有宽度,则 `width` 的使用值为该固有宽度;\n> 典型的例子是:拥有默认宽高的 `input` 当宽度的计算值为auto时,则宽度使用值为其默认的固有宽度\n* 若宽度的计算值为 `auto` 且元素有固有宽度,则 `width` 的使用值为该固有宽度;\n> 例子同上\n* 若宽度的计算值为 `auto` 且高度有 `非auto` 的计算值,并且元素有固有宽高比,则 `width` 的使用值为 `高度使用值 * 固有宽高比`;\n> 典型的例子:`img` 当只定义了其高度值时,其宽度将会根据固有宽高比进行等比设置\n* 除此之外,当 `width` 的计算值为 `auto` 时,则宽度的使用值为 `300px`\n> 典型的例子:比如iframe, canvas\n\n其它类型的置换元素,其宽度的定义都参照行内置换元素的定义。\n\n## 行内级置换和非置换元素的高度定义\n\n对于行内级非置换元素,高度设置是不适用的。\n\n对于行内级置换元素来说,其高度的设置需遵循以下几点:\n\n* 若宽高的计算值都为 `auto` 且元素有固有高度,则 `height` 的使用值为该固有高度;\n* 若高度的计算值为 `auto` 且元素有固有高度,则 `height` 的使用值为该固有高度;\n* 若高度的计算值为 `auto` 且宽度有 `非auto` 的计算值,并且元素有固有宽高比,则 `height` 的使用值为:`宽度使用值 / 固有宽高比`;\n* 若高度的计算值为 `auto` 且上述条件完全不符,则 `height` 的使用值 `不能大于150px`,且宽度不能大于长方形高度的2倍。\n\n其它类型的置换元素,其高度的定义都参照行内置换元素的定义。","slug":"css/置换和非置换元素","published":1,"updated":"2016-03-29T02:40:50.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvag700102ypkytcqoiv5"},{"title":"你需要了解的z-index世界","date":"2014-01-21T03:15:00.000Z","author":"杜瑶","_content":"\n## z-index的重要性\n\n在我看来,`z-index` 给了我们日常工作中以极大的帮助,我们用它来定义元素的层叠级别(stack level)。受益于它,你能做Popup, DropDown, Tips, 图文替换等等。\n\n在开始本篇之前,或许我们要先了解一下关于z-index的基本信息。\n\n## W3C这样描述\n\n每个元素都具有三维空间位置,除了水平和垂直位置外,还能在 \"Z轴\" 上层层相叠、排列。元素在 \"Z轴\" 方向上的呈现顺序,由层叠上下文和层叠级别决定。\n\n在文档中,每个元素仅属于一个层叠上下文。元素的层叠级别为整型,它描述了在相同层叠上下文中元素在 \"Z轴\" 上的呈现顺序。\n\n同一层叠上下文中,层叠级别大的显示在上,层叠级别小的显示在下,相同层叠级别时,遵循后来居上的原则,即其在HTML文档中的顺序。\n\n不同层叠上下文中,元素呈现顺序以父级层叠上下文的层叠级别来决定呈现的先后顺序,与自身的层叠级别无关。\n\n<!--more-->\n\n## z-index语法和应用\n\n z-index: auto | <integer>\n\n`z-index` 接受的属性值为:关键字auto和整数,整数可以是负值(Firefox2.0及之前不支持负值)。\n\n需要注意的是 `z-index` 虽然很给力,却只能应用于定位元素(即设置了 `position` 属性为非 `static` 值),其它情况下,`z-index` 将被忽略。\n\n对于定位元素而言,`z-index` 意味着:\n\n* 确定该元素在当前层叠上下文中的层叠级别。\n* 确定该元素是否创建了一个新的局部层叠上下文。\n\n## 创建层叠上下文\n\n在规范中说明:当某个元素的 `z-index` 未显式定义或者被指定为 `auto` 时,该元素不会产生新的局部层叠上下文。也就是说它可以和兄弟,祖先,后辈元素处在同一个堆叠上下文中,它们被放在一起比较层叠级别,儿子可以盖住祖先,父亲也可以盖住儿子,儿子甚至可以越过祖先,盖住祖先的兄弟,在层叠上下文中,它们是并级的关系。来看这样一个例子 `DEMO1`: [z-index与创建层叠上下文](http://demo.doyoe.com/css/z-index/stacking-context.htm)\n\n值得高兴的是,大部分浏览器都实现了这个特性;不过在IE6/7下,不论 `z-index` 值是否被显式定义,都将产生新的局部层叠上下文,也就是说子元素不可以越过是定位元素的父亲,子元素都处在新创建的局部层叠上下文中,只能在内部进行层叠级别的比较。\n\n## 深入浅出\n\n某区域内有个浮层提示或者下拉菜单,于是可能需要遮住该区域之下的区域。\n\n### HTML\n\n <div class=\"a\">\n ...\n <div class=\"tips\">我是一个简陋的浮层提示</div>\n </div>\n <div class=\"b\">\n ...\n </div>\n\n### CSS\n\n .a{position:relative;}\n .tips{position:absolute;z-index:99;}\n\n如上HTML/CSS代码,很显然,浮层 `tips` 将可以覆盖在其父级元素 `a` 的兄弟元素 `b` 之上。\n\n于是你的意图得到实现,效果如下 `图一`:\n\n![create stacking context](http://demo.doyoe.com/css/z-index/images/create-stacking-context.png)(图一)\n\n这是具体的实现例子 `DEMO2`: [z-index实现元素层叠](http://demo.doyoe.com/css/z-index/create-stacking-context-normal.htm)。\n\n不过很显然,从 `DEMO2` 来看,你依然无法准确的判断出在各浏览器下,`tips` 能盖住 `b` 是因为其父级的定位还是本身的定位。\n\n但是我们可以做这样一个测试,我们让 `b` 也拥有定位,Code如下:\n\n### CSS\n\n .a{position:relative;}\n .tips{position:absolute;z-index:99;}\n .b{position:relative;}\n\n这段代码run完之后,就比较纠结了,你能得到的效果将会如下 `图二`:\n\n![IE6/7 create stacking context bug](http://demo.doyoe.com/css/z-index/images/create-stacking-context-ie6-7-bug.png)(图二)\n\n当然要给出具体实现 `DEMO3`: [验证创建局部层叠上下文](http://demo.doyoe.com/css/z-index/create-stacking-context-ie6-7-bug.htm)。\n\n首先,我们来解读一下这个例子:因为 `a` 和 `b` 都是 `relative` 且没有定义 `z-index` (等同于z-index:auto),根据后来居上的原则,此时 `b` 的层叠级别是要高于 `a` 的,意思就是说 `a` 是无法遮住 `b` 的。不过从 `DEMO3` 中,我们看到 `a` 的子元素 `tips` 遮住了 `b`,这就表示 `tips` 能越过它,所以可以判断出 `a` 没有创建新的局部层叠上下文。很明显,这是完全吻合标准对此的定义。\n\n不过这是在非IE6/7之下结果。在IE6/7下,我们看到 `tips` 并没能遮住 `b`,也就是说 `tips` 无法越过父级,因为 `a` 创建了新的局部层叠上下文,而 `a` 的层叠级别又比 `b` 低,所以 `tips` 无法遮住 `b`,这也就是在IE6/7下常出现覆盖Bug的根源。\n\n结合 `DEMO2` 和 `DEMO3`,你能很肯定的得出以下结论:\n\n* 当定位元素没有显式定义z-index值时,不会创建新的局部层叠上下文\n* 子元素有可能和祖先的兄弟或者祖先兄弟的子元素处在同一个层叠上下文中\n\n在实际工作中,有些情况可能是你没注意或者已然存在的。比如你事先可能并不知道 `b` 也是定位元素,或者由于某些原因,你需要将其设置为定位元素,于是可能出现各种兼容问题。如果你不了解 `z-index` 是如何创建局部层叠上下文,且又没注意到IE6/7的实现错误,那么处理起这样的问题将会让你深陷泥潭。\n\n所以在实际的场景中,如果是为了相互覆盖而设置为定位,那么显式的定义 `z-index` 值,将可避免出现创建新局部层叠上下文差异。\n\n如果需要越过祖先和其它区块内部元素进行相互层叠,那么考虑IE6/7的情况,也应该尽量避免给父级元素进定位。\n\n## opacity与层叠上下文\n\n我们知道 `opacity` 属性是用来设置元素不透明度的。但可能知道 `opacity` 和层叠上下文有关的不多,不过没关系,这里我们简单聊聊这个话题,有两点必须注意:\n\n* 当opacity值小于1时,该元素会创建新的局部层叠上下文,也就是说它可以和定位元素进行层叠层别比较\n* 当opacity值小于1时,该元素拥有层叠级别且相当于z-index:0或auto,但不能定义 z-index ,除非本身是定位元素\n\n简单来说,当一个普通的元素定义了 `opacity` 的值小于1时(比如 opacity:.5),那么该元素的层叠级别将会高于普通元素,其效果类同于定位元素没有显式定义 `z-index` 的情况,唯一的区别是没有显式定义 `z-index` 的定位元素不会产生局部层叠上下文,而定义了 `opacity` 值小于1的元素会产生新的局部层叠上下文。\n\n### opacity猜想\n\n假定我们有 `a`, `b`, `c` 三个元素,它们相互层层覆盖在一起,如果这时将 `a` 元素定义为 `opacity:.8`,你知道结果会怎样吗?\n\n### HTML\n\n <div class=\"a\">a</div>\n <div class=\"b\">b</div>\n <div class=\"c\">c</div>\n\n### CSS\n\n .a,.b,.c{width:100px;height:100px;}\n .a{opacity:.8;background:#999;}\n .b{margin:-70px 0 0 30px;background:#090;}\n .c{margin:-70px 0 0 60px;background:#f00;}\n\n如果你看明白了我对于 `opacity` 与层叠上下文的描述,相信你可以猜到结果,是的,`a` 元素将会覆盖 `b` 和 `c` 元素,虽然它在HTML文档中出现在 `b` 和 `c` 之前,且不是定位元素。\n\n必须看看具体的示例不是么?`DEMO4`: [opacity与局部层叠上下文猜想](http://demo.doyoe.com/css/z-index/create-stacking-context-by-opacity.htm)。\n\n如果我们将 `b` 和 `c` 设置为定位元素,又将会如何呢?\n\n### CSS\n\n .a,.b,.c{width:100px;height:100px;}\n .a{opacity:.8;background:#999;}\n .b{position:relative;margin:-70px 0 0 30px;background:#090;}\n .c{position:relative;margin:-70px 0 0 60px;background:#f00;}\n\n不急,我们可以接着看示例 `DEMO5`: [opacity与局部层叠上下文猜想2](http://demo.doyoe.com/css/z-index/create-stacking-context-by-opacity-2.htm)。\n\n从 `DEMO4` 和 `DEMO5` 两例,我们可以验证:当一个普通元素定义了 `opacity` 为小于1的值时,该元素将像定位元素一样拥有层叠级别,可以覆盖普通元素,并且其层叠级别与未显式定义 `z-index` 的定位元素一样。\n\n### opacity创建局部层叠上下文\n\n与未显式定义 `z-index` 的定位元素唯一不同的是 `opacity` 值小于1的元素会创建局部层叠上下文。\n\n创建局部层叠上下文意味着什么,前文我们已经详述过。所以不再赘述,这里只给一个示例用以验证该特性。先奉上代码:\n\n### HTML\n\n <div class=\"a\">a\n <div class=\"d\">d</div>\n </div>\n <div class=\"b\">b</div>\n <div class=\"c\">c</div>\n\n### CSS\n\n .a,.b,.c,.d{width:100px;height:100px;}\n .a{opacity:.8;background:#999;}\n .b{position:relative;margin:-70px 0 0 30px;background:#090;}\n .c{position:relative;margin:-70px 0 0 60px;background:#f00;}\n .d{position:absolute;z-index:99;height:50px;background:#090;}\n\n你可以先看看具体结果 `DEMO6`: [opacity创建新局部层叠上下文](http://demo.doyoe.com/css/z-index/create-stacking-context-by-opacity-3.htm)。\n\n你会发现虽然 `a` 的子元素 `d` 将 `z-index` 定义为99,但 `d` 仍然无法遮住 `b` 和 `c` 元素,这是因为 `a` 创建了新的局部层叠上下文,`d` 元素无法超越父级。\n\n需要注意的是,此时就算 `a` 元素变成了定位元素,也不能改变其会创建新局部层叠上下文的命运,因为他设置了 `opacity:.8`。\n\n按照我们前文所说,如果 `a` 没有定义 `opacity:.8` ,但却像 `b` 和 `c` 元素一样设置了 `relative`,那么其子元素 `d` 将可以覆盖 `b` 和 `c`,至于这个例子就不再奉上了,大家随便写个测试一下即可。\n\n## 图文替换\n\n上述都是理论性的东西,相对枯燥,来个实际点的应用场景。\n\n我们聊聊图文替换的事,相对于使用较广的方案如:缩进正/负值(正/负text-indent)、超小字体、margin溢出、padding溢出、line-height溢出、透明字体、display:none、visibility:hidden等方案而言,使用 `z-index` 负值的方案,有一些明显的优势:\n\n* 无需考虑是否会有性能问题类同使用上述列举中的前几种方案(比如使用负缩进值-9999px,虽然此时文本被移到屏幕之外或者被裁减,但仍然会绘制一个宽9999px的盒子);\n* 没有像类似超小字体和透明字体一样的方案会需要一些额外的hack;\n* 不像display:none方案那样有SEO欺骗嫌疑;\n* 当图片加载失败时,可以显示文字;\n* and etc...\n\n先来看看一个图文替换的例子 `DEMO7`: [图文替换实例](http://demo.doyoe.com/css/z-index/back-top.htm)。\n\n在不同的网络环境下,它的表现如下 `图三`:\n\n![back top](http://demo.doyoe.com/css/z-index/images/back-top.png)(图三)\n\n具体的Code很简单:\n\n### HTML\n\n <a href=\"#top\" title=\"回到顶部\"><span>TOP▲</span></a>\n\n### CSS\n\n a,a span{display:inline-block;width:38px;height:38px;}\n a{background:url(images/ico.png) no-repeat;}\n a:hover{background-position:0 -39px;color:#fff;}\n a span{position:relative;z-index:-1;background-color:#eee;}\n a:hover span{background-color:#999;}\n\n你会发现我们将 span 设置为了 `z-index:-1`,此时它的层叠级别将比正常的元素还要低,所以它可以被其父元素超链接a盖住,从而在图片正常载入时显示父元素的背景图,在网络环境不好图片载入有问题时,显示自身。\n\n很多时候,要实现一个需求可能有无数种解决方案,能够适应情况越多的方案毫无疑问会脱颖而出,这就要求我们可以去更多的思考,而不是更多的拷贝。","source":"_posts/css/你需要了解的z-index世界.md","raw":"title: 你需要了解的z-index世界\ndate: 2014-01-21 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [z-index, w3c, 层叠上下文]\n---\n\n## z-index的重要性\n\n在我看来,`z-index` 给了我们日常工作中以极大的帮助,我们用它来定义元素的层叠级别(stack level)。受益于它,你能做Popup, DropDown, Tips, 图文替换等等。\n\n在开始本篇之前,或许我们要先了解一下关于z-index的基本信息。\n\n## W3C这样描述\n\n每个元素都具有三维空间位置,除了水平和垂直位置外,还能在 \"Z轴\" 上层层相叠、排列。元素在 \"Z轴\" 方向上的呈现顺序,由层叠上下文和层叠级别决定。\n\n在文档中,每个元素仅属于一个层叠上下文。元素的层叠级别为整型,它描述了在相同层叠上下文中元素在 \"Z轴\" 上的呈现顺序。\n\n同一层叠上下文中,层叠级别大的显示在上,层叠级别小的显示在下,相同层叠级别时,遵循后来居上的原则,即其在HTML文档中的顺序。\n\n不同层叠上下文中,元素呈现顺序以父级层叠上下文的层叠级别来决定呈现的先后顺序,与自身的层叠级别无关。\n\n<!--more-->\n\n## z-index语法和应用\n\n z-index: auto | <integer>\n\n`z-index` 接受的属性值为:关键字auto和整数,整数可以是负值(Firefox2.0及之前不支持负值)。\n\n需要注意的是 `z-index` 虽然很给力,却只能应用于定位元素(即设置了 `position` 属性为非 `static` 值),其它情况下,`z-index` 将被忽略。\n\n对于定位元素而言,`z-index` 意味着:\n\n* 确定该元素在当前层叠上下文中的层叠级别。\n* 确定该元素是否创建了一个新的局部层叠上下文。\n\n## 创建层叠上下文\n\n在规范中说明:当某个元素的 `z-index` 未显式定义或者被指定为 `auto` 时,该元素不会产生新的局部层叠上下文。也就是说它可以和兄弟,祖先,后辈元素处在同一个堆叠上下文中,它们被放在一起比较层叠级别,儿子可以盖住祖先,父亲也可以盖住儿子,儿子甚至可以越过祖先,盖住祖先的兄弟,在层叠上下文中,它们是并级的关系。来看这样一个例子 `DEMO1`: [z-index与创建层叠上下文](http://demo.doyoe.com/css/z-index/stacking-context.htm)\n\n值得高兴的是,大部分浏览器都实现了这个特性;不过在IE6/7下,不论 `z-index` 值是否被显式定义,都将产生新的局部层叠上下文,也就是说子元素不可以越过是定位元素的父亲,子元素都处在新创建的局部层叠上下文中,只能在内部进行层叠级别的比较。\n\n## 深入浅出\n\n某区域内有个浮层提示或者下拉菜单,于是可能需要遮住该区域之下的区域。\n\n### HTML\n\n <div class=\"a\">\n ...\n <div class=\"tips\">我是一个简陋的浮层提示</div>\n </div>\n <div class=\"b\">\n ...\n </div>\n\n### CSS\n\n .a{position:relative;}\n .tips{position:absolute;z-index:99;}\n\n如上HTML/CSS代码,很显然,浮层 `tips` 将可以覆盖在其父级元素 `a` 的兄弟元素 `b` 之上。\n\n于是你的意图得到实现,效果如下 `图一`:\n\n![create stacking context](http://demo.doyoe.com/css/z-index/images/create-stacking-context.png)(图一)\n\n这是具体的实现例子 `DEMO2`: [z-index实现元素层叠](http://demo.doyoe.com/css/z-index/create-stacking-context-normal.htm)。\n\n不过很显然,从 `DEMO2` 来看,你依然无法准确的判断出在各浏览器下,`tips` 能盖住 `b` 是因为其父级的定位还是本身的定位。\n\n但是我们可以做这样一个测试,我们让 `b` 也拥有定位,Code如下:\n\n### CSS\n\n .a{position:relative;}\n .tips{position:absolute;z-index:99;}\n .b{position:relative;}\n\n这段代码run完之后,就比较纠结了,你能得到的效果将会如下 `图二`:\n\n![IE6/7 create stacking context bug](http://demo.doyoe.com/css/z-index/images/create-stacking-context-ie6-7-bug.png)(图二)\n\n当然要给出具体实现 `DEMO3`: [验证创建局部层叠上下文](http://demo.doyoe.com/css/z-index/create-stacking-context-ie6-7-bug.htm)。\n\n首先,我们来解读一下这个例子:因为 `a` 和 `b` 都是 `relative` 且没有定义 `z-index` (等同于z-index:auto),根据后来居上的原则,此时 `b` 的层叠级别是要高于 `a` 的,意思就是说 `a` 是无法遮住 `b` 的。不过从 `DEMO3` 中,我们看到 `a` 的子元素 `tips` 遮住了 `b`,这就表示 `tips` 能越过它,所以可以判断出 `a` 没有创建新的局部层叠上下文。很明显,这是完全吻合标准对此的定义。\n\n不过这是在非IE6/7之下结果。在IE6/7下,我们看到 `tips` 并没能遮住 `b`,也就是说 `tips` 无法越过父级,因为 `a` 创建了新的局部层叠上下文,而 `a` 的层叠级别又比 `b` 低,所以 `tips` 无法遮住 `b`,这也就是在IE6/7下常出现覆盖Bug的根源。\n\n结合 `DEMO2` 和 `DEMO3`,你能很肯定的得出以下结论:\n\n* 当定位元素没有显式定义z-index值时,不会创建新的局部层叠上下文\n* 子元素有可能和祖先的兄弟或者祖先兄弟的子元素处在同一个层叠上下文中\n\n在实际工作中,有些情况可能是你没注意或者已然存在的。比如你事先可能并不知道 `b` 也是定位元素,或者由于某些原因,你需要将其设置为定位元素,于是可能出现各种兼容问题。如果你不了解 `z-index` 是如何创建局部层叠上下文,且又没注意到IE6/7的实现错误,那么处理起这样的问题将会让你深陷泥潭。\n\n所以在实际的场景中,如果是为了相互覆盖而设置为定位,那么显式的定义 `z-index` 值,将可避免出现创建新局部层叠上下文差异。\n\n如果需要越过祖先和其它区块内部元素进行相互层叠,那么考虑IE6/7的情况,也应该尽量避免给父级元素进定位。\n\n## opacity与层叠上下文\n\n我们知道 `opacity` 属性是用来设置元素不透明度的。但可能知道 `opacity` 和层叠上下文有关的不多,不过没关系,这里我们简单聊聊这个话题,有两点必须注意:\n\n* 当opacity值小于1时,该元素会创建新的局部层叠上下文,也就是说它可以和定位元素进行层叠层别比较\n* 当opacity值小于1时,该元素拥有层叠级别且相当于z-index:0或auto,但不能定义 z-index ,除非本身是定位元素\n\n简单来说,当一个普通的元素定义了 `opacity` 的值小于1时(比如 opacity:.5),那么该元素的层叠级别将会高于普通元素,其效果类同于定位元素没有显式定义 `z-index` 的情况,唯一的区别是没有显式定义 `z-index` 的定位元素不会产生局部层叠上下文,而定义了 `opacity` 值小于1的元素会产生新的局部层叠上下文。\n\n### opacity猜想\n\n假定我们有 `a`, `b`, `c` 三个元素,它们相互层层覆盖在一起,如果这时将 `a` 元素定义为 `opacity:.8`,你知道结果会怎样吗?\n\n### HTML\n\n <div class=\"a\">a</div>\n <div class=\"b\">b</div>\n <div class=\"c\">c</div>\n\n### CSS\n\n .a,.b,.c{width:100px;height:100px;}\n .a{opacity:.8;background:#999;}\n .b{margin:-70px 0 0 30px;background:#090;}\n .c{margin:-70px 0 0 60px;background:#f00;}\n\n如果你看明白了我对于 `opacity` 与层叠上下文的描述,相信你可以猜到结果,是的,`a` 元素将会覆盖 `b` 和 `c` 元素,虽然它在HTML文档中出现在 `b` 和 `c` 之前,且不是定位元素。\n\n必须看看具体的示例不是么?`DEMO4`: [opacity与局部层叠上下文猜想](http://demo.doyoe.com/css/z-index/create-stacking-context-by-opacity.htm)。\n\n如果我们将 `b` 和 `c` 设置为定位元素,又将会如何呢?\n\n### CSS\n\n .a,.b,.c{width:100px;height:100px;}\n .a{opacity:.8;background:#999;}\n .b{position:relative;margin:-70px 0 0 30px;background:#090;}\n .c{position:relative;margin:-70px 0 0 60px;background:#f00;}\n\n不急,我们可以接着看示例 `DEMO5`: [opacity与局部层叠上下文猜想2](http://demo.doyoe.com/css/z-index/create-stacking-context-by-opacity-2.htm)。\n\n从 `DEMO4` 和 `DEMO5` 两例,我们可以验证:当一个普通元素定义了 `opacity` 为小于1的值时,该元素将像定位元素一样拥有层叠级别,可以覆盖普通元素,并且其层叠级别与未显式定义 `z-index` 的定位元素一样。\n\n### opacity创建局部层叠上下文\n\n与未显式定义 `z-index` 的定位元素唯一不同的是 `opacity` 值小于1的元素会创建局部层叠上下文。\n\n创建局部层叠上下文意味着什么,前文我们已经详述过。所以不再赘述,这里只给一个示例用以验证该特性。先奉上代码:\n\n### HTML\n\n <div class=\"a\">a\n <div class=\"d\">d</div>\n </div>\n <div class=\"b\">b</div>\n <div class=\"c\">c</div>\n\n### CSS\n\n .a,.b,.c,.d{width:100px;height:100px;}\n .a{opacity:.8;background:#999;}\n .b{position:relative;margin:-70px 0 0 30px;background:#090;}\n .c{position:relative;margin:-70px 0 0 60px;background:#f00;}\n .d{position:absolute;z-index:99;height:50px;background:#090;}\n\n你可以先看看具体结果 `DEMO6`: [opacity创建新局部层叠上下文](http://demo.doyoe.com/css/z-index/create-stacking-context-by-opacity-3.htm)。\n\n你会发现虽然 `a` 的子元素 `d` 将 `z-index` 定义为99,但 `d` 仍然无法遮住 `b` 和 `c` 元素,这是因为 `a` 创建了新的局部层叠上下文,`d` 元素无法超越父级。\n\n需要注意的是,此时就算 `a` 元素变成了定位元素,也不能改变其会创建新局部层叠上下文的命运,因为他设置了 `opacity:.8`。\n\n按照我们前文所说,如果 `a` 没有定义 `opacity:.8` ,但却像 `b` 和 `c` 元素一样设置了 `relative`,那么其子元素 `d` 将可以覆盖 `b` 和 `c`,至于这个例子就不再奉上了,大家随便写个测试一下即可。\n\n## 图文替换\n\n上述都是理论性的东西,相对枯燥,来个实际点的应用场景。\n\n我们聊聊图文替换的事,相对于使用较广的方案如:缩进正/负值(正/负text-indent)、超小字体、margin溢出、padding溢出、line-height溢出、透明字体、display:none、visibility:hidden等方案而言,使用 `z-index` 负值的方案,有一些明显的优势:\n\n* 无需考虑是否会有性能问题类同使用上述列举中的前几种方案(比如使用负缩进值-9999px,虽然此时文本被移到屏幕之外或者被裁减,但仍然会绘制一个宽9999px的盒子);\n* 没有像类似超小字体和透明字体一样的方案会需要一些额外的hack;\n* 不像display:none方案那样有SEO欺骗嫌疑;\n* 当图片加载失败时,可以显示文字;\n* and etc...\n\n先来看看一个图文替换的例子 `DEMO7`: [图文替换实例](http://demo.doyoe.com/css/z-index/back-top.htm)。\n\n在不同的网络环境下,它的表现如下 `图三`:\n\n![back top](http://demo.doyoe.com/css/z-index/images/back-top.png)(图三)\n\n具体的Code很简单:\n\n### HTML\n\n <a href=\"#top\" title=\"回到顶部\"><span>TOP▲</span></a>\n\n### CSS\n\n a,a span{display:inline-block;width:38px;height:38px;}\n a{background:url(images/ico.png) no-repeat;}\n a:hover{background-position:0 -39px;color:#fff;}\n a span{position:relative;z-index:-1;background-color:#eee;}\n a:hover span{background-color:#999;}\n\n你会发现我们将 span 设置为了 `z-index:-1`,此时它的层叠级别将比正常的元素还要低,所以它可以被其父元素超链接a盖住,从而在图片正常载入时显示父元素的背景图,在网络环境不好图片载入有问题时,显示自身。\n\n很多时候,要实现一个需求可能有无数种解决方案,能够适应情况越多的方案毫无疑问会脱颖而出,这就要求我们可以去更多的思考,而不是更多的拷贝。","slug":"css/你需要了解的z-index世界","published":1,"updated":"2016-03-29T02:40:54.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvaga00182ypkypfsleum"},{"title":"margin系列之百分比","date":"2013-11-30T03:15:00.000Z","author":"杜瑶","_content":"\n## 你可能从没注意过它\n\n在 [margin系列之keyword auto](http://blog.doyoe.com/2013/11/29/css/margin系列之keyword auto/) 中,说过了 `margin` 值为 `auto` 的情况,这次要聊的是值为百分比的情形。\n\n我必须承认这是一个非常基础的知识点,但有一段时间我发现很多人对此有错误的认知。偶尔在面试或者分享的时候,我会问到这个问题,有人会脱口而出的告诉我他对此的感性理解。\n\n或许现在大多数人对此不屑一顾,但我仍想说一说,这样以后就可以不再问类似的问题了。\n\n## 假设有这样一个场景\n\n仍然以一个问题来开始,这是我之前在 [微博](http://weibo.com/doyoe) 发过的,原文是这样的:\n\n<!--more-->\n\n假设一个块级包含容器,宽1000px,高600px,块级子元素定义 `margin:10% 5%;` 大家说说 `margin` 的 `top, right, bottom, left` 计算值最终是多少?\n\n我记得得到不少 `100px 30px 100px 30px` 的反馈,我们来还原代码:\n\n### CSS:\n\n```css\n#demo{\n\twidth: 1000px;\n\theight: 600px;\n}\n#demo p{\n\tmargin: 10% 5%;\n}\n```\n\n### HTML:\n```html\n<div id=\"demo\">\n\t<p>恩,注意看我所在的位置。</p>\n</div>\n```\n\n事实告诉我们结果是 `100px 50px 100px 50px`,不论结果是否符合你的预期,我们先来看demo验证一下:[margin百分比结果猜想](//demo.doyoe.com/css/margin/percentage.htm),当然,你也根据上面还原的代码自己创建一个例子。\n\n## 为什么会这样?\n\n诧异吗?不用怀疑浏览器出了问题,因为这是正确的实现。\n\n规范中注明 `margin` 的百分比值参照其包含块的宽度进行计算。\n\n当然,它不会这么简单,和上篇文章 keyword auto 一样,这只发生在默认的 `writing-mode: horizontal-tb;` 和 `direction: ltr;` 的情况下。\n\n当书写模式变成纵向的时候,其参照将会变成包含块的高度。我们改变一下上面例子中的CSS书写模式:\n\n### CSS:\n\n```css\n#demo{\n\t-webkit-writing-mode: vertical-rl; /* for browsers of webkit engine */\n\twriting-mode: tb-rl; /* for ie */\n}\n```\n\n在 #demo 中添加这2句,其它code不变。也有个例子供观:[书写模式影响margin百分比的参照对象](//demo.doyoe.com/css/margin/percentage2.htm)。\n\n恩,这回的结果是 `60px 30px 60px 30px` ,因为其参照对象变成了包含块的高度。\n\n## 顺带再说说\n\n你是否觉得这不符合常规的感性认知?感性认知更多感觉应该横向参照包含块宽度,纵向参照包含块高度。\n\n其实这是为了要横向和纵向2个方向都创建相同的margin,如果它们的参照物不一致,那就无法得到两个方向相同的留白。\n\n你可能会问那为什么要选择宽度做参照而不是高度呢?\n\n这其实更多的要从CSS设计意图上去想,因为CSS的基础需求是排版,而通常我们所见的横排文字,其水平宽度一定(仔细回想一下,如果没有显式的定义宽度或者强制一行显示,都会遇到边界换行,而不是水平延展),垂直方向可以无限延展。但当书写模式为纵向时,其参照就变成了高度而不再是宽度了。\n\n还记得我们在 [margin系列之keyword auto](http://blog.doyoe.com/~posts/css/2013-11-29-margin%E7%B3%BB%E5%88%97%E4%B9%8Bkeyword%20auto.md) 留了个问题:为什么 `margin: auto;` 无法再纵向上垂直居中?其实原因也是上面所说的,因为纵向是可以无限延展的,所以没有一个一定的值可以被参照被用来计算。\n\n## 受书写模式影响的其它特性:\n\n* margin折叠\n* margin的keyword auto value\n* padding的百分比值\n\n## 可参考:\n\n* http://dev.w3.org/csswg/css-box/#the-margin-properties\n* http://dev.w3.org/csswg/css-box/#ltpercentagegt\n* http://dev.w3.org/csswg/css-box/#Calculating\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","source":"_posts/css/margin系列之百分比.md","raw":"title: margin系列之百分比\ndate: 2013-11-30 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [margin, w3c, margin百分比]\n---\n\n## 你可能从没注意过它\n\n在 [margin系列之keyword auto](http://blog.doyoe.com/2013/11/29/css/margin系列之keyword auto/) 中,说过了 `margin` 值为 `auto` 的情况,这次要聊的是值为百分比的情形。\n\n我必须承认这是一个非常基础的知识点,但有一段时间我发现很多人对此有错误的认知。偶尔在面试或者分享的时候,我会问到这个问题,有人会脱口而出的告诉我他对此的感性理解。\n\n或许现在大多数人对此不屑一顾,但我仍想说一说,这样以后就可以不再问类似的问题了。\n\n## 假设有这样一个场景\n\n仍然以一个问题来开始,这是我之前在 [微博](http://weibo.com/doyoe) 发过的,原文是这样的:\n\n<!--more-->\n\n假设一个块级包含容器,宽1000px,高600px,块级子元素定义 `margin:10% 5%;` 大家说说 `margin` 的 `top, right, bottom, left` 计算值最终是多少?\n\n我记得得到不少 `100px 30px 100px 30px` 的反馈,我们来还原代码:\n\n### CSS:\n\n```css\n#demo{\n\twidth: 1000px;\n\theight: 600px;\n}\n#demo p{\n\tmargin: 10% 5%;\n}\n```\n\n### HTML:\n```html\n<div id=\"demo\">\n\t<p>恩,注意看我所在的位置。</p>\n</div>\n```\n\n事实告诉我们结果是 `100px 50px 100px 50px`,不论结果是否符合你的预期,我们先来看demo验证一下:[margin百分比结果猜想](//demo.doyoe.com/css/margin/percentage.htm),当然,你也根据上面还原的代码自己创建一个例子。\n\n## 为什么会这样?\n\n诧异吗?不用怀疑浏览器出了问题,因为这是正确的实现。\n\n规范中注明 `margin` 的百分比值参照其包含块的宽度进行计算。\n\n当然,它不会这么简单,和上篇文章 keyword auto 一样,这只发生在默认的 `writing-mode: horizontal-tb;` 和 `direction: ltr;` 的情况下。\n\n当书写模式变成纵向的时候,其参照将会变成包含块的高度。我们改变一下上面例子中的CSS书写模式:\n\n### CSS:\n\n```css\n#demo{\n\t-webkit-writing-mode: vertical-rl; /* for browsers of webkit engine */\n\twriting-mode: tb-rl; /* for ie */\n}\n```\n\n在 #demo 中添加这2句,其它code不变。也有个例子供观:[书写模式影响margin百分比的参照对象](//demo.doyoe.com/css/margin/percentage2.htm)。\n\n恩,这回的结果是 `60px 30px 60px 30px` ,因为其参照对象变成了包含块的高度。\n\n## 顺带再说说\n\n你是否觉得这不符合常规的感性认知?感性认知更多感觉应该横向参照包含块宽度,纵向参照包含块高度。\n\n其实这是为了要横向和纵向2个方向都创建相同的margin,如果它们的参照物不一致,那就无法得到两个方向相同的留白。\n\n你可能会问那为什么要选择宽度做参照而不是高度呢?\n\n这其实更多的要从CSS设计意图上去想,因为CSS的基础需求是排版,而通常我们所见的横排文字,其水平宽度一定(仔细回想一下,如果没有显式的定义宽度或者强制一行显示,都会遇到边界换行,而不是水平延展),垂直方向可以无限延展。但当书写模式为纵向时,其参照就变成了高度而不再是宽度了。\n\n还记得我们在 [margin系列之keyword auto](http://blog.doyoe.com/~posts/css/2013-11-29-margin%E7%B3%BB%E5%88%97%E4%B9%8Bkeyword%20auto.md) 留了个问题:为什么 `margin: auto;` 无法再纵向上垂直居中?其实原因也是上面所说的,因为纵向是可以无限延展的,所以没有一个一定的值可以被参照被用来计算。\n\n## 受书写模式影响的其它特性:\n\n* margin折叠\n* margin的keyword auto value\n* padding的百分比值\n\n## 可参考:\n\n* http://dev.w3.org/csswg/css-box/#the-margin-properties\n* http://dev.w3.org/csswg/css-box/#ltpercentagegt\n* http://dev.w3.org/csswg/css-box/#Calculating\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","slug":"css/margin系列之百分比","published":1,"updated":"2016-04-12T08:25:03.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvagd001f2ypknqlrfofi"},{"title":"margin系列之布局篇","date":"2013-12-31T03:15:00.000Z","author":"杜瑶","_content":"\n## 前端工程师对CSS的基本诉求\n\n布局能力或许是Web前端工程师对CSS的最基本的诉求,当开始进入到这个岗位,就避免不了要和CSS打交道,而和CSS交往,布局当然是不可或缺的。\n\n很遗憾的是,CSS2.1之前都没有出现真正意义上的布局属性,直至现如今的CSS3,才开始出现了一些,如:flex, grid 等,不过其兼容性及国内浏览器的使用情况,真令人捉急。\n\n不过,有需求就会有变通,对于达成布局目的,已衍生出各式各样的方法,如:float, inline-block, table, absolute 等等。\n\n<!--more-->\n\n## margin的布局之道\n\n其实,这个话题有点脱离 `margin` 的能力范围,因为单纯的 `margin` 并无法完成复杂布局,它更多做的是辅助,但却又难以替代。\n\n## 经典左右结构\n\n两栏结构应该是最常见和经典的网页呈现之一吧?如下 `图一`:\n\n![classsic layout](http://demo.doyoe.com/css/margin/images/layout-1.png)(图一)\n\n相信对于这样一个网页呈现,你不会陌生。那么你有多少种方案可以达成该布局?我想,4至5种应该是保守估计吧?\n\n这次,我们只看 `margin` 是如何做的。\n\n## absolute + margin 方式\n\n### HTML\n\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <aside id=\"aside\">侧边栏固定宽度</aside>\n <div id=\"main\">主内容栏自适应宽度</div>\n </div>\n <footer id=\"ft\">底部</footer>\n\n### CSS\n\n #aside{\n position:absolute;\n top:0;\n left:0;\n width:200px;\n }\n #main{\n margin-left:210px;\n }\n\n如上关键代码,我们即可实现 `图一` 布局,该布局有一个特点就是,`#main` 可以自适应可用空间。\n\n假定 `HTML` 是给定的,我们来解读一下 `CSS` 代码:\n\n我们知道块级元素的特性之一是换新行,也就是说,如果想让 `#main` 和 `#aside` 在同行显示,我们要么改变其显示属性为 `inline-level`(即之前说的inline-block布局方式),要么改变其流方式(absolute, float, flex and etc...)。\n\n如上述代码,我们使用了 `absolute`,即让 '#aside' 脱离常规流,通过绝对定位到想要的位置。\n\n### 主内容栏自适应宽度\n\n同时你会发现,我们并有改变 `#main` 的显示属性或者流方式,也就是说其仍然具备块级元素的特性,所以它会自动适应剩余宽度,即我们常说的自适应宽度。\n\n我们并不希望 `#main` 区域会包含 `#aside` 在内,于是利用 `margin` 给 '#aside' 预留出足够其显示的空间,即可达成我们所要的布局。\n\n可能你会问为什么是 `margin-left:210px` 而不是 `200px`,实际确实应该是 `200px`,多出来的 `10px` 只是为了创建一个列间隙,与布局实现无关。\n\n来看看具体的实现 `DEMO1`: [margin+absolute布局:左栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/absolute-margin.html)\n\n就这样,是不是很简单?其实它还有亮点,那就是:\n\n### 任意调整列顺序\n\n在不修改 `HTML` 的情况下,只需简单的修改 `CSS`,我们即可让左右两栏的顺序调换,来看代码:\n\n### CSS\n\n #aside{\n position:absolute;\n top:0;\n right:0;\n width:200px;\n }\n #main{\n margin-right:210px;\n }\n\n其实现原理没变,同样看看 `DEMO2`: [margin+absolute布局:右栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/absolute-margin-2.html)\n\n### 主内容优先显示\n\n可以更Cool一点,你觉得呢?很多时候,你也许会考虑到,不论在何种情况下,总想保证主要的内容优先于次要的内容呈现给用户,那么,怎么做?\n\n很简单,只需要将主要内容的HTML排在次要内容的HTML之前即可,因为它是顺序加载渲染的。我们可以这样:\n\n### HTML\n\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <div id=\"main\">主内容栏自适应宽度</div>\n <aside id=\"aside\">侧边栏固定宽度</aside>\n </div>\n <footer id=\"ft\">底部</footer>\n\n是的,我们只需要将 `#main` 的HTML挪到 `#aside` 的HTML前面,令人兴奋的是,改变HTML之后,CSS不需要做任何改变。我们来看 `DEMO3`: [margin+absolute布局:左栏固定主内容自适应,主内容有限显示](http://demo.doyoe.com/css/margin/layout/absolute-margin-3.html)\n\n当然,调正列顺序的 `DEMO4`: [margin+absolute布局:右栏固定主内容自适应,主内容有限显示](http://demo.doyoe.com/css/margin/layout/absolute-margin-4.html) 也同样简单,我们只需要写HTML时注意一下即可。\n\n### 致命缺陷\n\n列举了 `absolute+margin` 布局的很多优点,但只说一个问题,就足以让你在是否选用这种方式时深思熟虑,是什么呢?\n\n我们知道 `absolute` 是定位流,脱离正常排版,也就是说绝对定位元素不影响其上下文的排版方式,你意识到我想说什么了么?\n\nOK,用代码来演示:\n\n### HTML\n\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <div id=\"main\">主内容栏自适应宽度</div>\n <aside id=\"aside\">侧边栏固定宽度,我的内容可能比主内容多,高度比主内容栏高</aside>\n </div>\n <footer id=\"ft\">底部</footer>\n\n看完代码,估计你猜到了。是的,`#aside` 无法撑开父元素的高度,它将会溢出父元素区域,结果如下图:\n\n![classsic layout](http://demo.doyoe.com/css/margin/images/layout-2.png)(图二)\n\n来看看这缺陷所导致的情况 `DEMO5`: [margin+absolute布局的致命缺陷](http://demo.doyoe.com/css/margin/layout/absolute-margin-5.html)\n\n此时假设你设置父元素 `overflow:hidden` 那么溢出部分将会被裁减,同样不符合布局意图,无法可破。所以在内容量不可控的场景,不推荐使用这种方式。\n\n## float + margin 方式\n\n和 `absolute + margin` 方式一样,`float + margin` 方式一样是经典的利用来布局的方案,并且被更广泛使用。我们仍然以 `图一` 为例,来看代码:\n\n### HTML\n\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <aside id=\"aside\">侧边栏固定宽度</aside>\n <div id=\"main\">主内容栏自适应宽度</div>\n </div>\n <footer id=\"ft\">底部</footer>\n\n### CSS\n\n #aside{\n float:left;\n width:200px;\n }\n #main{\n margin-left:210px;\n }\n\n如上述代码,我们使用了 `float`,即从图文环绕形态演变而来。当 `#aside` 定义了 `float`,那么紧随其后的元素将会环绕在其周围。不过环绕并不是我们想要的结果,我们想要的是 '#main' 也自成封闭矩形,所以利用 `margin` 留出足够 `#aside` 显示的空间,中断环绕即可。\n\n当然,此时 `#main` 也是自适应宽度的,来看具体实例 `DEMO6`: [margin+float布局:左栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/float-margin.html)\n\n它是否也具备可任意调整列顺序的特点?何不一试?\n\n### CSS\n\n #aside{\n float:right;\n width:200px;\n }\n #main{\n margin-right:210px;\n }\n\n\n看过 `DEMO7`: [margin+float布局:右栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/float-margin-2.html),你会发现,是的,这种方式也支持任意调整列顺序,很棒。\n\n从这种趋势看来,貌似 `float + margin` 的方式会成为黑马,不过遗憾的告诉你,这种方式无法支持主内容优先显示。但我们有更Cool的解决方案。\n\n## float + 负margin 方式\n\n接下来我要说的大家可能都猜到了,对,经典的圣杯布局。至于圣杯的名字由来,大家可以自行Google,这里不做赘述。\n\n恩,HTML当然是使用主内容优先显示的那种:\n\n### HTML\n\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <div id=\"main\">主内容栏自适应宽度</div>\n <aside id=\"aside\">侧边栏固定宽度</aside>\n </div>\n <footer id=\"ft\">底部</footer>\n\n### CSS\n\n #bd{\n padding-left:210px;\n }\n #aside{\n float:left;\n position:relative;\n left:-210px;\n width:200px;\n margin-left:-100%;\n }\n #main{\n float:left;\n width:100%;\n }\n\n如上代码,既是圣杯布局的核心Code,如果你看懂了,你会发现,这其实很简单,不是么?\n\n简单解释一下上面的CSS Code,首先我们是在做一个左侧固定宽度,右侧自适应宽度的布局。我们说过要让块级元素在同行显示的条件:改变显示方式,改变流方式,这里我们选择了使用 `float` 来将 `#main` 和 `#aside` 变成浮动流。\n\nOK,这时我们具备 `#main` 和 `#aside` 能在同行显示的前置条件。我们知道,浮动元素其宽度如果没有显式定义,则由其内容决定。正好,`#aside` 是定宽的,所以显示给它定义 `width:200px`,但此时 `#main` 该怎么办?不设置 `width` 不对,因为宽度将被内容左右,设置 `width:100%` 也不对,因为这样的话,就没有 `#aside` 的立足之地了,正确的应该是 `width: calc(100% - 200px)`,不是么?可惜,这是新特性,只好作罢。\n\n变通?是的,有的时候稍微换个思路,你会觉得豁然开朗。\n\n`#main` 不是要自适应吗?那就给它个 `100%`,怎么做?我们在包含块 `#bd` 中就将 `#aside` 的宽度刨除,宽度全部都给 `#main`。恩,我们只需要这样 `#bd{padding-left:210px;}` (10px仍然是用来做间隙的),这时 `#main` 就可以设置 `width:100%` 了,由于 `#bd` 设置了 `padding`,所以已在左边预留出了一块宽 `210px` 的区域。此时的问题在于如果将 `#aside` 挪到这个地方,你想对了,我们是在聊 `负margin` 布局,自然需要利用上。\n\n`#aside{margin-left:-100%;}` 这样可以了吗?很明显,这样还不行,此时 `#aside` 和 `#main` 的起始位置将会重合,因为 `#aside` 的 `margin-left` 计算值是相对包含块来计算的,而此时包含块的宽度等于 `#main` 的宽度。\n\n如何让 `#aside` 再向左偏移 `210px`?显然 `margin` 是不行了,因为我们已经用掉它了。如果你看过之前的文章的话,你可能还记得,有一篇文章讲 [margin系列之与相对偏移的异同](http://blog.doyoe.com/2013/12/02/css/margin系列之与相对偏移的异同/)。恩,是的,这时我们可以借助相对偏移。\n\n向左偏移 `210px` 是件很简单的事:`#aside{position:relative;left:-210px;}`。\n\n至此,你的布局OK了,这就是圣杯的实现方式。来看已实现好的示例 `DEMO8`: [圣杯:左栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/holy-grail.html)\n\n当然,圣杯布局必须可以任意调整列顺序,要不,怎么能说是更Cool些的方案呢?\n\n### CSS\n\n #bd{\n padding-right:210px;\n }\n #aside{\n float:left;\n position:relative;\n right:-210px;\n width:200px;\n margin-left:-200px;\n }\n #main{\n float:left;\n width:100%;\n }\n\n这个就直接看示例好了,不再一一解释代码 `DEMO9`: [圣杯:右栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/holy-grail-2.html)\n\n所以圣杯布局具备前两种方式共同的优点,同时没有他们的不足,但圣杯本身也有一些问题,在IE6/7下报废,不过不用慌,因为它可被修复。\n\n你想到方法了吗?\n\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","source":"_posts/css/margin系列之布局篇.md","raw":"title: margin系列之布局篇\ndate: 2013-12-31 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [margin, w3c, margin layout, 圣杯布局, holy grail]\n---\n\n## 前端工程师对CSS的基本诉求\n\n布局能力或许是Web前端工程师对CSS的最基本的诉求,当开始进入到这个岗位,就避免不了要和CSS打交道,而和CSS交往,布局当然是不可或缺的。\n\n很遗憾的是,CSS2.1之前都没有出现真正意义上的布局属性,直至现如今的CSS3,才开始出现了一些,如:flex, grid 等,不过其兼容性及国内浏览器的使用情况,真令人捉急。\n\n不过,有需求就会有变通,对于达成布局目的,已衍生出各式各样的方法,如:float, inline-block, table, absolute 等等。\n\n<!--more-->\n\n## margin的布局之道\n\n其实,这个话题有点脱离 `margin` 的能力范围,因为单纯的 `margin` 并无法完成复杂布局,它更多做的是辅助,但却又难以替代。\n\n## 经典左右结构\n\n两栏结构应该是最常见和经典的网页呈现之一吧?如下 `图一`:\n\n![classsic layout](http://demo.doyoe.com/css/margin/images/layout-1.png)(图一)\n\n相信对于这样一个网页呈现,你不会陌生。那么你有多少种方案可以达成该布局?我想,4至5种应该是保守估计吧?\n\n这次,我们只看 `margin` 是如何做的。\n\n## absolute + margin 方式\n\n### HTML\n\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <aside id=\"aside\">侧边栏固定宽度</aside>\n <div id=\"main\">主内容栏自适应宽度</div>\n </div>\n <footer id=\"ft\">底部</footer>\n\n### CSS\n\n #aside{\n position:absolute;\n top:0;\n left:0;\n width:200px;\n }\n #main{\n margin-left:210px;\n }\n\n如上关键代码,我们即可实现 `图一` 布局,该布局有一个特点就是,`#main` 可以自适应可用空间。\n\n假定 `HTML` 是给定的,我们来解读一下 `CSS` 代码:\n\n我们知道块级元素的特性之一是换新行,也就是说,如果想让 `#main` 和 `#aside` 在同行显示,我们要么改变其显示属性为 `inline-level`(即之前说的inline-block布局方式),要么改变其流方式(absolute, float, flex and etc...)。\n\n如上述代码,我们使用了 `absolute`,即让 '#aside' 脱离常规流,通过绝对定位到想要的位置。\n\n### 主内容栏自适应宽度\n\n同时你会发现,我们并有改变 `#main` 的显示属性或者流方式,也就是说其仍然具备块级元素的特性,所以它会自动适应剩余宽度,即我们常说的自适应宽度。\n\n我们并不希望 `#main` 区域会包含 `#aside` 在内,于是利用 `margin` 给 '#aside' 预留出足够其显示的空间,即可达成我们所要的布局。\n\n可能你会问为什么是 `margin-left:210px` 而不是 `200px`,实际确实应该是 `200px`,多出来的 `10px` 只是为了创建一个列间隙,与布局实现无关。\n\n来看看具体的实现 `DEMO1`: [margin+absolute布局:左栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/absolute-margin.html)\n\n就这样,是不是很简单?其实它还有亮点,那就是:\n\n### 任意调整列顺序\n\n在不修改 `HTML` 的情况下,只需简单的修改 `CSS`,我们即可让左右两栏的顺序调换,来看代码:\n\n### CSS\n\n #aside{\n position:absolute;\n top:0;\n right:0;\n width:200px;\n }\n #main{\n margin-right:210px;\n }\n\n其实现原理没变,同样看看 `DEMO2`: [margin+absolute布局:右栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/absolute-margin-2.html)\n\n### 主内容优先显示\n\n可以更Cool一点,你觉得呢?很多时候,你也许会考虑到,不论在何种情况下,总想保证主要的内容优先于次要的内容呈现给用户,那么,怎么做?\n\n很简单,只需要将主要内容的HTML排在次要内容的HTML之前即可,因为它是顺序加载渲染的。我们可以这样:\n\n### HTML\n\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <div id=\"main\">主内容栏自适应宽度</div>\n <aside id=\"aside\">侧边栏固定宽度</aside>\n </div>\n <footer id=\"ft\">底部</footer>\n\n是的,我们只需要将 `#main` 的HTML挪到 `#aside` 的HTML前面,令人兴奋的是,改变HTML之后,CSS不需要做任何改变。我们来看 `DEMO3`: [margin+absolute布局:左栏固定主内容自适应,主内容有限显示](http://demo.doyoe.com/css/margin/layout/absolute-margin-3.html)\n\n当然,调正列顺序的 `DEMO4`: [margin+absolute布局:右栏固定主内容自适应,主内容有限显示](http://demo.doyoe.com/css/margin/layout/absolute-margin-4.html) 也同样简单,我们只需要写HTML时注意一下即可。\n\n### 致命缺陷\n\n列举了 `absolute+margin` 布局的很多优点,但只说一个问题,就足以让你在是否选用这种方式时深思熟虑,是什么呢?\n\n我们知道 `absolute` 是定位流,脱离正常排版,也就是说绝对定位元素不影响其上下文的排版方式,你意识到我想说什么了么?\n\nOK,用代码来演示:\n\n### HTML\n\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <div id=\"main\">主内容栏自适应宽度</div>\n <aside id=\"aside\">侧边栏固定宽度,我的内容可能比主内容多,高度比主内容栏高</aside>\n </div>\n <footer id=\"ft\">底部</footer>\n\n看完代码,估计你猜到了。是的,`#aside` 无法撑开父元素的高度,它将会溢出父元素区域,结果如下图:\n\n![classsic layout](http://demo.doyoe.com/css/margin/images/layout-2.png)(图二)\n\n来看看这缺陷所导致的情况 `DEMO5`: [margin+absolute布局的致命缺陷](http://demo.doyoe.com/css/margin/layout/absolute-margin-5.html)\n\n此时假设你设置父元素 `overflow:hidden` 那么溢出部分将会被裁减,同样不符合布局意图,无法可破。所以在内容量不可控的场景,不推荐使用这种方式。\n\n## float + margin 方式\n\n和 `absolute + margin` 方式一样,`float + margin` 方式一样是经典的利用来布局的方案,并且被更广泛使用。我们仍然以 `图一` 为例,来看代码:\n\n### HTML\n\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <aside id=\"aside\">侧边栏固定宽度</aside>\n <div id=\"main\">主内容栏自适应宽度</div>\n </div>\n <footer id=\"ft\">底部</footer>\n\n### CSS\n\n #aside{\n float:left;\n width:200px;\n }\n #main{\n margin-left:210px;\n }\n\n如上述代码,我们使用了 `float`,即从图文环绕形态演变而来。当 `#aside` 定义了 `float`,那么紧随其后的元素将会环绕在其周围。不过环绕并不是我们想要的结果,我们想要的是 '#main' 也自成封闭矩形,所以利用 `margin` 留出足够 `#aside` 显示的空间,中断环绕即可。\n\n当然,此时 `#main` 也是自适应宽度的,来看具体实例 `DEMO6`: [margin+float布局:左栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/float-margin.html)\n\n它是否也具备可任意调整列顺序的特点?何不一试?\n\n### CSS\n\n #aside{\n float:right;\n width:200px;\n }\n #main{\n margin-right:210px;\n }\n\n\n看过 `DEMO7`: [margin+float布局:右栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/float-margin-2.html),你会发现,是的,这种方式也支持任意调整列顺序,很棒。\n\n从这种趋势看来,貌似 `float + margin` 的方式会成为黑马,不过遗憾的告诉你,这种方式无法支持主内容优先显示。但我们有更Cool的解决方案。\n\n## float + 负margin 方式\n\n接下来我要说的大家可能都猜到了,对,经典的圣杯布局。至于圣杯的名字由来,大家可以自行Google,这里不做赘述。\n\n恩,HTML当然是使用主内容优先显示的那种:\n\n### HTML\n\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <div id=\"main\">主内容栏自适应宽度</div>\n <aside id=\"aside\">侧边栏固定宽度</aside>\n </div>\n <footer id=\"ft\">底部</footer>\n\n### CSS\n\n #bd{\n padding-left:210px;\n }\n #aside{\n float:left;\n position:relative;\n left:-210px;\n width:200px;\n margin-left:-100%;\n }\n #main{\n float:left;\n width:100%;\n }\n\n如上代码,既是圣杯布局的核心Code,如果你看懂了,你会发现,这其实很简单,不是么?\n\n简单解释一下上面的CSS Code,首先我们是在做一个左侧固定宽度,右侧自适应宽度的布局。我们说过要让块级元素在同行显示的条件:改变显示方式,改变流方式,这里我们选择了使用 `float` 来将 `#main` 和 `#aside` 变成浮动流。\n\nOK,这时我们具备 `#main` 和 `#aside` 能在同行显示的前置条件。我们知道,浮动元素其宽度如果没有显式定义,则由其内容决定。正好,`#aside` 是定宽的,所以显示给它定义 `width:200px`,但此时 `#main` 该怎么办?不设置 `width` 不对,因为宽度将被内容左右,设置 `width:100%` 也不对,因为这样的话,就没有 `#aside` 的立足之地了,正确的应该是 `width: calc(100% - 200px)`,不是么?可惜,这是新特性,只好作罢。\n\n变通?是的,有的时候稍微换个思路,你会觉得豁然开朗。\n\n`#main` 不是要自适应吗?那就给它个 `100%`,怎么做?我们在包含块 `#bd` 中就将 `#aside` 的宽度刨除,宽度全部都给 `#main`。恩,我们只需要这样 `#bd{padding-left:210px;}` (10px仍然是用来做间隙的),这时 `#main` 就可以设置 `width:100%` 了,由于 `#bd` 设置了 `padding`,所以已在左边预留出了一块宽 `210px` 的区域。此时的问题在于如果将 `#aside` 挪到这个地方,你想对了,我们是在聊 `负margin` 布局,自然需要利用上。\n\n`#aside{margin-left:-100%;}` 这样可以了吗?很明显,这样还不行,此时 `#aside` 和 `#main` 的起始位置将会重合,因为 `#aside` 的 `margin-left` 计算值是相对包含块来计算的,而此时包含块的宽度等于 `#main` 的宽度。\n\n如何让 `#aside` 再向左偏移 `210px`?显然 `margin` 是不行了,因为我们已经用掉它了。如果你看过之前的文章的话,你可能还记得,有一篇文章讲 [margin系列之与相对偏移的异同](http://blog.doyoe.com/2013/12/02/css/margin系列之与相对偏移的异同/)。恩,是的,这时我们可以借助相对偏移。\n\n向左偏移 `210px` 是件很简单的事:`#aside{position:relative;left:-210px;}`。\n\n至此,你的布局OK了,这就是圣杯的实现方式。来看已实现好的示例 `DEMO8`: [圣杯:左栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/holy-grail.html)\n\n当然,圣杯布局必须可以任意调整列顺序,要不,怎么能说是更Cool些的方案呢?\n\n### CSS\n\n #bd{\n padding-right:210px;\n }\n #aside{\n float:left;\n position:relative;\n right:-210px;\n width:200px;\n margin-left:-200px;\n }\n #main{\n float:left;\n width:100%;\n }\n\n这个就直接看示例好了,不再一一解释代码 `DEMO9`: [圣杯:右栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/holy-grail-2.html)\n\n所以圣杯布局具备前两种方式共同的优点,同时没有他们的不足,但圣杯本身也有一些问题,在IE6/7下报废,不过不用慌,因为它可被修复。\n\n你想到方法了吗?\n\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","slug":"css/margin系列之布局篇","published":1,"updated":"2016-04-19T04:01:23.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvagg001m2ypkivnatu8j"},{"title":"margin系列之外边距折叠","date":"2013-12-04T03:15:00.000Z","author":"杜瑶","_content":"\n## 不怀疑你也在工作中遇见过\n\n几乎可以不用怀疑,前端工作中的你一定遇见过 `margin` 折叠。\n\n不确定?别着急,你可能写过这样的代码:\n\n### CSS:\n\n```css\np{\n\tmargin: 50px;\n}\n```\n\n### HTML:\n\n```html\n<div id=\"demo\">\n\t<p>我是一个华丽的段落,别看我文字少</p>\n\t<p>我是另一个华丽的段落</p>\n</div>\n```\n\n大家觉得这 `2p` 之间会发生点什么?是会合体呢?还是分开?来看看 `DEMO1` [margin折叠](http://demo.doyoe.com/css/margin/collapse-margin.htm)\n\n<!--more-->\n\n好吧,它们真的合体了。按照常规思路,这 `2p` 之间的空白应该是第一个 `p` 的 `margin-bottom` 50px 加上第二 `p` 的 `margin-top` 50px,即 `50 + 50px = 100px` ,但结果总是出乎意料不是么?它们之间只剩下了 `50px`,这就是 `margin折叠`。所以任何人遇见过我都不会觉得意外,因为这样的Code看起来没有任何问题。\n\n## 它们之间到底发生了些什么?\n\n这 `2p` 内部到底发生了什么,才会有这样的表现?\n\n早在CSS1中就有对 `margin` 折叠的说明,我们来看看:\n\n> 原文:The width of the margin on non-floating block-level elements specifies the minimum distance to the edges of surrounding boxes. Two or more adjoining vertical margins (i.e., with no border, padding or content between them) are collapsed to use the maximum of the margin values. In most cases, after collapsing the vertical margins the result is visually more pleasing and closer to what the designer expects.\n\n> 翻译:外边距用来指定非浮动元素与其周围盒子边缘的最小距离。两个或两个以上的相邻的垂直外边距会被折叠并使用它们之间最大的那个外边距值。多数情况下,折叠垂直外边距可以在视觉上显得更美观,也更贴近设计师的预期。\n\n从这段话中,我们能获得一些有用的信息:\n\n* 发生折叠需要是相邻的非浮动元素;\n* 折叠发生在垂直外边距上,即margin-top/margin-bottom;\n* 折叠后取其中最大的那个margin值作为最终值;\n\n所以 `DEMO1` 中的 `2p` 符合折叠的条件,相邻且都不是浮动元素,于是它们就自然合体了。至于取最大的那个值作为折叠后的最终值,因为都是50px,所以无所谓谁谁谁了。\n\n## 为什么会有margin折叠这样的设计?\n\n从上文中,应该能知道个大概?在前面的文章中,我们说过,CSS的基本模型是排版。只是前端工程师现在做得更多的是 `布局` 而非 `文字排版`,但CSS并未界定这两者的区别。而 `margin` 折叠是为实现文本排版的段落间距而提供的特性。所以很多时候 `margin` 折叠的特性会带给我们诸多疑惑。\n\n再回到 `DEMO1` 仔细看看,你会惊讶的发现,其实你只要设置每个 `p` 有相同的垂直外边距,由于发生会 `margin` 折叠,所有的 `p` 之间,及包含块与 `p` 之间的间隙都是相同的,非常美妙且实现简单,不是么?这正印证了我们引用 `CSS1` 中的那短话:多数情况下,折叠垂直外边距可以在视觉上显得更美观,也更贴近设计师的预期。\n\n## 浮动元素真的不会发生margin折叠吗?\n\n质疑精神一直都是进步最重要的驱动力之一,我们为什么不能呢?改下代码看看:\n\n### CSS:\n\n```css\np{\n\tfloat: left;\n\tmargin: 50px;\n}\n```\n\n只改CSS代码,HTML不变。迫不及待的想看到验证情况,来吧,还等什么。`DEMO2` [验证浮动元素是否会发生margin折叠](http://demo.doyoe.com/css/margin/float-collapse-margin.htm)。\n\n结果告诉我们,真的没有折叠,`2p` 间的间隙足足有 `100px`。\n\n剩下的2点大家就自行验证吧,相信你能得到满意的额测试结果。\n\n## 仅此而已?\n\n回想一下我们在 [margin系列之百分比](http://blog.doyoe.com/2013/11/30/css/margin系列之百分比/) 文中提到过受书写模式影响的一些特性,非常不幸,`margin` 折叠正好是其中之一。\n\n是的,在CSS2及后续的规范中,将`margin` 折叠描述得更为详尽了。\n\n在水平书写模式下,发生 `margin` 折叠的是垂直方向,即 `margin-top/margin-bottom`,在垂直书写模式下,`margin` 折叠发生在水平方向上,即 `margin-right/margin-left`。\n\n## 现在我们来解释一下到底什么是margin折叠?\n\n在CSS中,两个或以上的块元素(可能是兄弟,也可能不是)之间的相邻外边距可以被合并成一个单独的外边距。通过此方式合并的外边距被称为折叠,且产生的已合并的外边距被称为折叠外边距。\n\n处于同一个块级上下文中的块元素,没有行框、没有间隙、没有内边距和边框隔开它们,这样的元素垂直边缘毗邻,则称之为相邻。\n\n### 什么是垂直边缘毗邻?\n\n* 元素的上外边距和其属于常规流中的第一个孩子的上外边距。\n* 元素的下外边距和其属于常规流中的下一个兄弟的上外边距。\n* 属于常规流中的最后一个孩子的下外边距和其父亲的下外边距,如果其父亲的高度计算值为 `auto`。\n* 元素的上、下外边距,如果该元素没有建立新的块级格式上下文,且 `min-height` 的计算值为零、` height ` 的计算值为零或 `auto`、且没有属于常规流中的孩子。\n\n说得很清楚了,我想是的。你可能需要注意的是发生 `margin` 折叠的元素不一定是兄弟关系,也能是父子或祖先的关系。\n\n## 如何避免margin折叠?\n\n我想肯定有人要问,那我不想有 `margin` 折叠的情况发生,该怎么办?其实从上面的规则中,我们已经可以抽出避免 `margin` 折叠的条件来。\n\n* `margin` 折叠元素只发生在块元素上;\n* 浮动元素不与其他元素 `margin` 折叠;\n* 定义了属性overflow且值不为visible(即创建了新的块级格式化上下文)的块元素,不与它的子元素发生`margin` 折叠;\n* 绝对定位元素的 `margin` 不与任何 `margin` 发生折叠。\n* 特殊:根元素的 `margin` 不与其它任何 `margin` 发生折叠;\n* 如果常规流中的一个块元素没有 `border-top`、`padding-top`,且其第一个浮动的块级子元素没有间隙,则该元素的上外边距会与其常规流中的第一个块级子元素的上外边距折叠。\n 可能有些绕,我们验证一下 [`DEMO3`](http://demo.doyoe.com/css/margin/collapse-margin-verify.htm),在其第一个浮动子元素加个全角空格做间隙,来个反证 [`DEMO4`](http://demo.doyoe.com/css/margin/collapse-margin-re-verify.htm)\n* 如果一个元素的 `min-height` 属性为0,且没有上或下边框以及上或下内边距,且 `height` 为0或者 `auto`,且不包含行框,且其属于常规流的所有孩子的外边距都折叠了,则折叠其外边距。验证一下 [`DEMO5`](http://demo.doyoe.com/css/margin/collapse-margin-verify-2.htm)\n\n## 这样干掉margin折叠\n\n如果不想发生 `margin` 折叠,那么你可以根据上面的规则得到方法,不是么?我把它改成非块元素,让它浮动,让它绝对定位,让它 `overflow:hidden` [`DEMO6`](http://demo.doyoe.com/css/margin/destroy-collapse-margin-by-overflow.htm),用边框隔开它们 [`DEMO7`](http://demo.doyoe.com/css/margin/destroy-collapse-margin-by-border.htm)...随你怎样,信手拈来。\n\n今天状态不太好,有些地方写得欠妥,之后可能会修改一下。\n\nBTW: 这篇文章里可能有不少之前文章中没出现过的名词,比如:块级上下文、行框、常规流,如果你对此不甚了解,可以先找资料看看,我以后会讲到。\n\nenjoy it.\n\n\n## 可参考:\n\n* http://www.w3.org/TR/css3-box/#margins\n* http://www.w3.org/TR/css3-box/#collapsing-margins\n* http://dev.w3.org/csswg/css-box/#collapsing-margins\n* http://www.w3.org/TR/CSS1/#vertical-formatting\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","source":"_posts/css/margin系列之外边距折叠.md","raw":"title: margin系列之外边距折叠\ndate: 2013-12-04 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [margin, w3c, margin折叠]\n---\n\n## 不怀疑你也在工作中遇见过\n\n几乎可以不用怀疑,前端工作中的你一定遇见过 `margin` 折叠。\n\n不确定?别着急,你可能写过这样的代码:\n\n### CSS:\n\n```css\np{\n\tmargin: 50px;\n}\n```\n\n### HTML:\n\n```html\n<div id=\"demo\">\n\t<p>我是一个华丽的段落,别看我文字少</p>\n\t<p>我是另一个华丽的段落</p>\n</div>\n```\n\n大家觉得这 `2p` 之间会发生点什么?是会合体呢?还是分开?来看看 `DEMO1` [margin折叠](http://demo.doyoe.com/css/margin/collapse-margin.htm)\n\n<!--more-->\n\n好吧,它们真的合体了。按照常规思路,这 `2p` 之间的空白应该是第一个 `p` 的 `margin-bottom` 50px 加上第二 `p` 的 `margin-top` 50px,即 `50 + 50px = 100px` ,但结果总是出乎意料不是么?它们之间只剩下了 `50px`,这就是 `margin折叠`。所以任何人遇见过我都不会觉得意外,因为这样的Code看起来没有任何问题。\n\n## 它们之间到底发生了些什么?\n\n这 `2p` 内部到底发生了什么,才会有这样的表现?\n\n早在CSS1中就有对 `margin` 折叠的说明,我们来看看:\n\n> 原文:The width of the margin on non-floating block-level elements specifies the minimum distance to the edges of surrounding boxes. Two or more adjoining vertical margins (i.e., with no border, padding or content between them) are collapsed to use the maximum of the margin values. In most cases, after collapsing the vertical margins the result is visually more pleasing and closer to what the designer expects.\n\n> 翻译:外边距用来指定非浮动元素与其周围盒子边缘的最小距离。两个或两个以上的相邻的垂直外边距会被折叠并使用它们之间最大的那个外边距值。多数情况下,折叠垂直外边距可以在视觉上显得更美观,也更贴近设计师的预期。\n\n从这段话中,我们能获得一些有用的信息:\n\n* 发生折叠需要是相邻的非浮动元素;\n* 折叠发生在垂直外边距上,即margin-top/margin-bottom;\n* 折叠后取其中最大的那个margin值作为最终值;\n\n所以 `DEMO1` 中的 `2p` 符合折叠的条件,相邻且都不是浮动元素,于是它们就自然合体了。至于取最大的那个值作为折叠后的最终值,因为都是50px,所以无所谓谁谁谁了。\n\n## 为什么会有margin折叠这样的设计?\n\n从上文中,应该能知道个大概?在前面的文章中,我们说过,CSS的基本模型是排版。只是前端工程师现在做得更多的是 `布局` 而非 `文字排版`,但CSS并未界定这两者的区别。而 `margin` 折叠是为实现文本排版的段落间距而提供的特性。所以很多时候 `margin` 折叠的特性会带给我们诸多疑惑。\n\n再回到 `DEMO1` 仔细看看,你会惊讶的发现,其实你只要设置每个 `p` 有相同的垂直外边距,由于发生会 `margin` 折叠,所有的 `p` 之间,及包含块与 `p` 之间的间隙都是相同的,非常美妙且实现简单,不是么?这正印证了我们引用 `CSS1` 中的那短话:多数情况下,折叠垂直外边距可以在视觉上显得更美观,也更贴近设计师的预期。\n\n## 浮动元素真的不会发生margin折叠吗?\n\n质疑精神一直都是进步最重要的驱动力之一,我们为什么不能呢?改下代码看看:\n\n### CSS:\n\n```css\np{\n\tfloat: left;\n\tmargin: 50px;\n}\n```\n\n只改CSS代码,HTML不变。迫不及待的想看到验证情况,来吧,还等什么。`DEMO2` [验证浮动元素是否会发生margin折叠](http://demo.doyoe.com/css/margin/float-collapse-margin.htm)。\n\n结果告诉我们,真的没有折叠,`2p` 间的间隙足足有 `100px`。\n\n剩下的2点大家就自行验证吧,相信你能得到满意的额测试结果。\n\n## 仅此而已?\n\n回想一下我们在 [margin系列之百分比](http://blog.doyoe.com/2013/11/30/css/margin系列之百分比/) 文中提到过受书写模式影响的一些特性,非常不幸,`margin` 折叠正好是其中之一。\n\n是的,在CSS2及后续的规范中,将`margin` 折叠描述得更为详尽了。\n\n在水平书写模式下,发生 `margin` 折叠的是垂直方向,即 `margin-top/margin-bottom`,在垂直书写模式下,`margin` 折叠发生在水平方向上,即 `margin-right/margin-left`。\n\n## 现在我们来解释一下到底什么是margin折叠?\n\n在CSS中,两个或以上的块元素(可能是兄弟,也可能不是)之间的相邻外边距可以被合并成一个单独的外边距。通过此方式合并的外边距被称为折叠,且产生的已合并的外边距被称为折叠外边距。\n\n处于同一个块级上下文中的块元素,没有行框、没有间隙、没有内边距和边框隔开它们,这样的元素垂直边缘毗邻,则称之为相邻。\n\n### 什么是垂直边缘毗邻?\n\n* 元素的上外边距和其属于常规流中的第一个孩子的上外边距。\n* 元素的下外边距和其属于常规流中的下一个兄弟的上外边距。\n* 属于常规流中的最后一个孩子的下外边距和其父亲的下外边距,如果其父亲的高度计算值为 `auto`。\n* 元素的上、下外边距,如果该元素没有建立新的块级格式上下文,且 `min-height` 的计算值为零、` height ` 的计算值为零或 `auto`、且没有属于常规流中的孩子。\n\n说得很清楚了,我想是的。你可能需要注意的是发生 `margin` 折叠的元素不一定是兄弟关系,也能是父子或祖先的关系。\n\n## 如何避免margin折叠?\n\n我想肯定有人要问,那我不想有 `margin` 折叠的情况发生,该怎么办?其实从上面的规则中,我们已经可以抽出避免 `margin` 折叠的条件来。\n\n* `margin` 折叠元素只发生在块元素上;\n* 浮动元素不与其他元素 `margin` 折叠;\n* 定义了属性overflow且值不为visible(即创建了新的块级格式化上下文)的块元素,不与它的子元素发生`margin` 折叠;\n* 绝对定位元素的 `margin` 不与任何 `margin` 发生折叠。\n* 特殊:根元素的 `margin` 不与其它任何 `margin` 发生折叠;\n* 如果常规流中的一个块元素没有 `border-top`、`padding-top`,且其第一个浮动的块级子元素没有间隙,则该元素的上外边距会与其常规流中的第一个块级子元素的上外边距折叠。\n 可能有些绕,我们验证一下 [`DEMO3`](http://demo.doyoe.com/css/margin/collapse-margin-verify.htm),在其第一个浮动子元素加个全角空格做间隙,来个反证 [`DEMO4`](http://demo.doyoe.com/css/margin/collapse-margin-re-verify.htm)\n* 如果一个元素的 `min-height` 属性为0,且没有上或下边框以及上或下内边距,且 `height` 为0或者 `auto`,且不包含行框,且其属于常规流的所有孩子的外边距都折叠了,则折叠其外边距。验证一下 [`DEMO5`](http://demo.doyoe.com/css/margin/collapse-margin-verify-2.htm)\n\n## 这样干掉margin折叠\n\n如果不想发生 `margin` 折叠,那么你可以根据上面的规则得到方法,不是么?我把它改成非块元素,让它浮动,让它绝对定位,让它 `overflow:hidden` [`DEMO6`](http://demo.doyoe.com/css/margin/destroy-collapse-margin-by-overflow.htm),用边框隔开它们 [`DEMO7`](http://demo.doyoe.com/css/margin/destroy-collapse-margin-by-border.htm)...随你怎样,信手拈来。\n\n今天状态不太好,有些地方写得欠妥,之后可能会修改一下。\n\nBTW: 这篇文章里可能有不少之前文章中没出现过的名词,比如:块级上下文、行框、常规流,如果你对此不甚了解,可以先找资料看看,我以后会讲到。\n\nenjoy it.\n\n\n## 可参考:\n\n* http://www.w3.org/TR/css3-box/#margins\n* http://www.w3.org/TR/css3-box/#collapsing-margins\n* http://dev.w3.org/csswg/css-box/#collapsing-margins\n* http://www.w3.org/TR/CSS1/#vertical-formatting\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","slug":"css/margin系列之外边距折叠","published":1,"updated":"2016-04-12T08:26:58.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvagk001w2ypkeljv8cye"},{"title":"margin系列之圣杯拾遗","date":"2016-04-28T03:15:00.000Z","author":"杜瑶","_content":"\n## 接续\n\n我回翻了一下之前的几篇文章,发现在 [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/) 中还有些问题没说完,所以准备补全一下。\n\n不过这2篇文章的时间的跨度有点,在阅读本文之前,大家可以先翻读一下3年前的那篇文章。\n\n## 没填完的坑\n\n在 [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/) 一文结尾时,我们谈到了圣杯布局,说这个布局的实现本身存在了一些问题:“在IE6/7下报废,不过不用慌,因为它可被修复”。\n\n我一直以为写完了,然而今天看了下发现还有坑没填。所以本文会讲讲这些问题是什么以及如何修复。\n\n<!--more-->\n\n## 圣杯布局的一些谈资\n\n下面节选一段来自网路上对圣杯的描述(略有调整):\n\n> 圣杯是宗教传说中的圣物,耶稣曾经用这个杯子吩咐门徒喝下里面象征他的血的红葡萄酒,借此创立了受难纪念仪式。因为这个特殊的原因,后来有些人认为这个杯子具有某种神奇的能力。很多传说相信,如果能找到这个圣杯而喝下其盛过的水就将返老还童、死而复生并且获得永生,这个传说广泛延续到很多文学、影视、游戏等作品中。\n\n而所谓的圣杯布局也并不是一个具象的形容,更多的是指借希望于它能够实现某种特殊的布局。\n\n这种特殊布局的需求是:侧边栏宽度固定,主内容栏宽度自适应,并且需要将主内容栏放在侧边栏前面,以便优先渲染(不论是两栏或者三栏,需求都是一样的)。\n\n## 遗留的问题\n\n在 [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/) 里,我们用圣杯布局做了 `图0` 的效果。\n\n![图0:classsic layout](http://demo.doyoe.com/css/margin/images/layout-1.png)\n\n下面是我们在上篇文章中写的圣杯布局核心代码(当然,这个 `#demo` 容器你也可以利用 `body` 来取代):\n\n### HTML\n```html\n<div id=\"demo\">\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <div id=\"main\">主内容栏自适应宽度</div>\n <aside id=\"aside\">侧边栏固定宽度</aside>\n </div>\n <footer id=\"ft\">底部</footer>\n</div>\n```\n\n### CSS\n```css\n#demo {\n width: 80%;\n}\n#bd {\n *zoom: 1;\n overflow: hidden;\n padding-left: 210px;\n}\n#main {\n float: left;\n width: 100%;\n}\n#aside {\n _display: inline;\n float: left;\n position: relative;\n left: -210px;\n width: 200px;\n margin-left: -100%;\n}\n```\n\n大家可以使用各种浏览器来测试一下这个示例 [圣杯:左栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/holy-grail.html)\n\n一般情况下,你会发现除了`IE6`外,其它的浏览器看起来都算正常,然而问题的范围可能并不仅限于这些,大部分问题没被看出只不过是因为没到达边界。\n\n问题列表:\n\n* `IE6` 布局错乱,侧边栏位置不对;\n* `IE7` resize窗口时,侧边栏会跳动;\n* `IE7及其它浏览器`,当窗口缩小到主内容栏的宽度小于侧边栏的宽度时,布局错乱;\n\n上面这几个问题,大家其实都可以自己去测测看,应该是当前的实现中都存在的。\n\n对于第3点,我们看看上述的代码实现,还是能非常轻松的理解的。因为侧边栏定义了 `margin-left: -100%`,在这个场景中,`100%` 其实就等同于主内容栏的宽度。如果主内容栏的宽度小于侧边栏,那么侧边栏偏移了一个比自己小的宽度,自然是放不下自己的。\n\n对于第1点,这个就有点意思了,基本上这又算是IE6的一个Bug,描述一下这个Bug的现象:\n\n在IE6中,假定是处于默认的书写模式下,当一个浮动的元素定义了margin的值是一个百分比,那么此时,浮动元素的margin百分比参照最近的清除了浮动的包含块的父元素的宽度进行计算,或者参照body。(然而标准描述只是参考包含块的宽度进行计算,详情请参阅我之前的文章 [margin系列之百分比](/2013/11/30/css/margin系列之百分比/))\n\n我会用一段伪代码来详述这个事,代码如下:\n\n```html\nbody > c > b > a\n```\n\n假设上述代码中的 `a` 就是我们说的浮动元素,正常情况下 `a` 设置了一个百分比的margin,百分比是要参考 `b` 的宽度进行计算的。\n\n然后 `IE6` 并没有实现这个规则,它的特征是:\n\n* 浮动元素 `a` 定义了百分比的margin,假设它的祖先元素 `b` 和 `c` 都没有清除浮动,那么就会参照 `body` 的宽度进行百分比换算;\n* 假设 `b` 清除了浮动,那么就会参照 `c` 的宽度进行百分比换算;\n\n对于这个Bug,我写了一个示例,大家可以对照着描述来看这个例子:[浮动margin百分比在ie6上的Bug](http://demo.doyoe.com/css/margin/layout/margin-percentage-bug-on-ie6.html)\n\n好了,知道了在 `IE6` 中有这个Bug之后,关于问题列表中的第1点,我们就也能够理解了,因为 `position: relative; left: -210px;` 这个定义对于 `IE6` 来讲,其实是多余的。\n\n对于第2点,应该是在resize过程中,不断的重绘造成的,它需要不断的去计算这个百分比的使用值。\n\n## 杀死它们\n\n所以如果想使得圣杯布局变得更靠谱一些,我们要么就是见招拆招,修复这个问题(比如说为 `IE6` 重置掉 `position: relative; left: -210px;` 定义),要么就避免遇上这些问题,我更喜欢第二种的方式。\n\n我们如何做才能避免遇上这些问题?\n\n其实我们可以细看一下,问题列表中的几点,其实都是因浮动元素的margin百分比引发的。既然浮动元素的margin百分比,在各浏览器下需要差异化处理,那么干脆弃用百分比,改用固定值(复杂度其实并没有上升,因为用百分比的时候,还得给`left`定义一个固定的偏移量)。\n\n那么,新的问题来了。如果改用margin固定值,我们要如何知道这个固定值是多少?比如在这个布局中我们的容器宽度是视窗的 `80%`,我们无法得到侧边栏需要偏移的固定值是多少,除非我们使用运算表达式 `calc()`,但是它的兼容性并不是我们想要的。\n\n这是因为主内容栏和侧边栏都是左浮动,并且侧边栏浮动在主内容栏后面,所以我们需要让侧边栏偏移 `#main + #aside` 的宽度,才能让侧边栏出现在正确的位置。\n\n所以,其实我们可以转变一下思路,让主内容栏和侧边栏朝不同的方向浮动,这样的话,侧边栏只需要偏移自身的宽度就能出现在正确的位置上,不在需要使用margin百分比值。\n\n## 新路\n\n我们按照前面说的将代码调整一下,HTML不变:\n\n### CSS\n```css\n#demo {\n width: 80%;\n}\n#bd {\n *zoom: 1;\n overflow: hidden;\n padding-left: 210px;\n}\n#main {\n float: right;\n width: 100%;\n}\n#aside {\n _display: inline;\n float: left;\n width: 200px;\n margin: 0 10px 0 -210px;\n}\n```\n\n我们来看看这个 [进化的圣杯:左栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/holy-grail-3.html) 效果,你会欣喜的发现,问题列表中的3个问题都被我们跳过了,这是一个更健康的实现。\n\n当然,它也是可以任意调整列呈现顺序的,我们只需要这样就行:\n\n### CSS\n```css\n#demo {\n width: 80%;\n}\n#bd {\n *zoom: 1;\n overflow: hidden;\n padding-right: 210px;\n}\n#main {\n float: left;\n width: 100%;\n}\n#aside {\n _display: inline;\n float: right;\n width: 200px;\n margin: 0 -210px 0 10px;\n}\n```\n\n于是我们就得到了一个 [进化的圣杯:右栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/holy-grail-4.html) 的布局。\n\n总体来讲,圣杯布局只是有能力达成我们的需求,但就其本身来讲并不是太先进的布局,灵活性相对局限。\n\n另外,你可能关注到了代码中出现的 `margin` 定义,它并不是一个单纯的负值,而是多了一个 `10px`,这其实是为了解决 `IE6/7` 右浮动子元素的向右负偏移量最大只能是自身宽度的问题(感兴趣的童鞋可以看看这个测试:[右浮动margin-right负值在ie67上的bug](http://demo.doyoe.com/css/margin/layout/margin-right-bug-on-ie67.html)),所以额外处理的间隙,但这其实并不影响其他浏览器。\n\n## 最后\n\n本文,更多的在于补全之前的那篇文章,算个简单的完结。本意其实并不在于说让大家去折腾那些古老而无趣的浏览器,而是希望看到的是对待任何事情,我们首先要觉得它可以解决,然后再抽丝剥茧的去实现它。未知并不可怕,可怕是恐惧未知。","source":"_posts/css/margin系列之圣杯拾遗.md","raw":"title: margin系列之圣杯拾遗\ndate: 2016-4-28 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [margin, w3c, margin layout, 圣杯布局, holy grail]\n---\n\n## 接续\n\n我回翻了一下之前的几篇文章,发现在 [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/) 中还有些问题没说完,所以准备补全一下。\n\n不过这2篇文章的时间的跨度有点,在阅读本文之前,大家可以先翻读一下3年前的那篇文章。\n\n## 没填完的坑\n\n在 [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/) 一文结尾时,我们谈到了圣杯布局,说这个布局的实现本身存在了一些问题:“在IE6/7下报废,不过不用慌,因为它可被修复”。\n\n我一直以为写完了,然而今天看了下发现还有坑没填。所以本文会讲讲这些问题是什么以及如何修复。\n\n<!--more-->\n\n## 圣杯布局的一些谈资\n\n下面节选一段来自网路上对圣杯的描述(略有调整):\n\n> 圣杯是宗教传说中的圣物,耶稣曾经用这个杯子吩咐门徒喝下里面象征他的血的红葡萄酒,借此创立了受难纪念仪式。因为这个特殊的原因,后来有些人认为这个杯子具有某种神奇的能力。很多传说相信,如果能找到这个圣杯而喝下其盛过的水就将返老还童、死而复生并且获得永生,这个传说广泛延续到很多文学、影视、游戏等作品中。\n\n而所谓的圣杯布局也并不是一个具象的形容,更多的是指借希望于它能够实现某种特殊的布局。\n\n这种特殊布局的需求是:侧边栏宽度固定,主内容栏宽度自适应,并且需要将主内容栏放在侧边栏前面,以便优先渲染(不论是两栏或者三栏,需求都是一样的)。\n\n## 遗留的问题\n\n在 [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/) 里,我们用圣杯布局做了 `图0` 的效果。\n\n![图0:classsic layout](http://demo.doyoe.com/css/margin/images/layout-1.png)\n\n下面是我们在上篇文章中写的圣杯布局核心代码(当然,这个 `#demo` 容器你也可以利用 `body` 来取代):\n\n### HTML\n```html\n<div id=\"demo\">\n <header id=\"hd\">头部</header>\n <div id=\"bd\">\n <div id=\"main\">主内容栏自适应宽度</div>\n <aside id=\"aside\">侧边栏固定宽度</aside>\n </div>\n <footer id=\"ft\">底部</footer>\n</div>\n```\n\n### CSS\n```css\n#demo {\n width: 80%;\n}\n#bd {\n *zoom: 1;\n overflow: hidden;\n padding-left: 210px;\n}\n#main {\n float: left;\n width: 100%;\n}\n#aside {\n _display: inline;\n float: left;\n position: relative;\n left: -210px;\n width: 200px;\n margin-left: -100%;\n}\n```\n\n大家可以使用各种浏览器来测试一下这个示例 [圣杯:左栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/holy-grail.html)\n\n一般情况下,你会发现除了`IE6`外,其它的浏览器看起来都算正常,然而问题的范围可能并不仅限于这些,大部分问题没被看出只不过是因为没到达边界。\n\n问题列表:\n\n* `IE6` 布局错乱,侧边栏位置不对;\n* `IE7` resize窗口时,侧边栏会跳动;\n* `IE7及其它浏览器`,当窗口缩小到主内容栏的宽度小于侧边栏的宽度时,布局错乱;\n\n上面这几个问题,大家其实都可以自己去测测看,应该是当前的实现中都存在的。\n\n对于第3点,我们看看上述的代码实现,还是能非常轻松的理解的。因为侧边栏定义了 `margin-left: -100%`,在这个场景中,`100%` 其实就等同于主内容栏的宽度。如果主内容栏的宽度小于侧边栏,那么侧边栏偏移了一个比自己小的宽度,自然是放不下自己的。\n\n对于第1点,这个就有点意思了,基本上这又算是IE6的一个Bug,描述一下这个Bug的现象:\n\n在IE6中,假定是处于默认的书写模式下,当一个浮动的元素定义了margin的值是一个百分比,那么此时,浮动元素的margin百分比参照最近的清除了浮动的包含块的父元素的宽度进行计算,或者参照body。(然而标准描述只是参考包含块的宽度进行计算,详情请参阅我之前的文章 [margin系列之百分比](/2013/11/30/css/margin系列之百分比/))\n\n我会用一段伪代码来详述这个事,代码如下:\n\n```html\nbody > c > b > a\n```\n\n假设上述代码中的 `a` 就是我们说的浮动元素,正常情况下 `a` 设置了一个百分比的margin,百分比是要参考 `b` 的宽度进行计算的。\n\n然后 `IE6` 并没有实现这个规则,它的特征是:\n\n* 浮动元素 `a` 定义了百分比的margin,假设它的祖先元素 `b` 和 `c` 都没有清除浮动,那么就会参照 `body` 的宽度进行百分比换算;\n* 假设 `b` 清除了浮动,那么就会参照 `c` 的宽度进行百分比换算;\n\n对于这个Bug,我写了一个示例,大家可以对照着描述来看这个例子:[浮动margin百分比在ie6上的Bug](http://demo.doyoe.com/css/margin/layout/margin-percentage-bug-on-ie6.html)\n\n好了,知道了在 `IE6` 中有这个Bug之后,关于问题列表中的第1点,我们就也能够理解了,因为 `position: relative; left: -210px;` 这个定义对于 `IE6` 来讲,其实是多余的。\n\n对于第2点,应该是在resize过程中,不断的重绘造成的,它需要不断的去计算这个百分比的使用值。\n\n## 杀死它们\n\n所以如果想使得圣杯布局变得更靠谱一些,我们要么就是见招拆招,修复这个问题(比如说为 `IE6` 重置掉 `position: relative; left: -210px;` 定义),要么就避免遇上这些问题,我更喜欢第二种的方式。\n\n我们如何做才能避免遇上这些问题?\n\n其实我们可以细看一下,问题列表中的几点,其实都是因浮动元素的margin百分比引发的。既然浮动元素的margin百分比,在各浏览器下需要差异化处理,那么干脆弃用百分比,改用固定值(复杂度其实并没有上升,因为用百分比的时候,还得给`left`定义一个固定的偏移量)。\n\n那么,新的问题来了。如果改用margin固定值,我们要如何知道这个固定值是多少?比如在这个布局中我们的容器宽度是视窗的 `80%`,我们无法得到侧边栏需要偏移的固定值是多少,除非我们使用运算表达式 `calc()`,但是它的兼容性并不是我们想要的。\n\n这是因为主内容栏和侧边栏都是左浮动,并且侧边栏浮动在主内容栏后面,所以我们需要让侧边栏偏移 `#main + #aside` 的宽度,才能让侧边栏出现在正确的位置。\n\n所以,其实我们可以转变一下思路,让主内容栏和侧边栏朝不同的方向浮动,这样的话,侧边栏只需要偏移自身的宽度就能出现在正确的位置上,不在需要使用margin百分比值。\n\n## 新路\n\n我们按照前面说的将代码调整一下,HTML不变:\n\n### CSS\n```css\n#demo {\n width: 80%;\n}\n#bd {\n *zoom: 1;\n overflow: hidden;\n padding-left: 210px;\n}\n#main {\n float: right;\n width: 100%;\n}\n#aside {\n _display: inline;\n float: left;\n width: 200px;\n margin: 0 10px 0 -210px;\n}\n```\n\n我们来看看这个 [进化的圣杯:左栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/holy-grail-3.html) 效果,你会欣喜的发现,问题列表中的3个问题都被我们跳过了,这是一个更健康的实现。\n\n当然,它也是可以任意调整列呈现顺序的,我们只需要这样就行:\n\n### CSS\n```css\n#demo {\n width: 80%;\n}\n#bd {\n *zoom: 1;\n overflow: hidden;\n padding-right: 210px;\n}\n#main {\n float: left;\n width: 100%;\n}\n#aside {\n _display: inline;\n float: right;\n width: 200px;\n margin: 0 -210px 0 10px;\n}\n```\n\n于是我们就得到了一个 [进化的圣杯:右栏固定主内容自适应](http://demo.doyoe.com/css/margin/layout/holy-grail-4.html) 的布局。\n\n总体来讲,圣杯布局只是有能力达成我们的需求,但就其本身来讲并不是太先进的布局,灵活性相对局限。\n\n另外,你可能关注到了代码中出现的 `margin` 定义,它并不是一个单纯的负值,而是多了一个 `10px`,这其实是为了解决 `IE6/7` 右浮动子元素的向右负偏移量最大只能是自身宽度的问题(感兴趣的童鞋可以看看这个测试:[右浮动margin-right负值在ie67上的bug](http://demo.doyoe.com/css/margin/layout/margin-right-bug-on-ie67.html)),所以额外处理的间隙,但这其实并不影响其他浏览器。\n\n## 最后\n\n本文,更多的在于补全之前的那篇文章,算个简单的完结。本意其实并不在于说让大家去折腾那些古老而无趣的浏览器,而是希望看到的是对待任何事情,我们首先要觉得它可以解决,然后再抽丝剥茧的去实现它。未知并不可怕,可怕是恐惧未知。","slug":"css/margin系列之圣杯拾遗","published":1,"updated":"2016-04-28T03:33:10.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvagm00222ypkms8jz73c"},{"title":"margin系列之内秀篇(二)","date":"2013-12-14T03:15:00.000Z","author":"杜瑶","_content":"\n## 可挖掘性\n\n之前已经写过一篇关于 `margin` 应用场景的文章:[margin系列之内秀篇](http://blog.doyoe.com/2013/12/06/css/margin系列之内秀篇/),当然,它的应用场景会远大于文中所述,无法一一列举。\n\n所以本篇权当是对此的补遗好了,各位客官如有比较Cool的想法都可以留言给我,我会视情况补丁进来。\n\n## 1像素圆角\n\n<!--more-->\n\n这有什么好聊的吗?`border-radius` 瞬间可将之秒杀。恩,有的时候你不得不承认CSS3真是一把大杀器。不过当年我们是怎么做的?(会暴露年龄么?)\n\n先看看我们要做什么,`图一`:\n\n![1px圆角](http://demo.doyoe.com/css/margin/images/radius.png)(图一)\n\n如上图一,我们会这样写:\n\n### HTML\n\n <div id=\"demo\">\n <a href=\"?\"><span>1px圆角</span></a>\n <a href=\"?\"><span>确定</span></a>\n <a href=\"?\"><span>取消</span></a>\n </div>\n\n### CSS\n\n #demo a,#demo span{\n display:inline-block;\n vertical-align:top;\n }\n #demo span{\n margin:1px -1px; /* 关键规则 */\n }\n\n一条CSS规则我们就可以实现1px圆角,你信吗?来看`DEMO1`:[margin实现1px圆角](http://demo.doyoe.com/css/margin/radius.htm)\n\n看到`DEMO1`的结果后,你会发现我们确实做到了1px圆角,很简单,有木有?在没有 `border-radius` 的年代,我们也很欢乐。\n\n看到Code后,我想应该不用太解释为什么可以实现?\n\nBTW,多像素圆角也可以参考这种方式来实现,如果你实在不想用图片的话。\n\n## 已知宽高元素水平垂直居中\n\n必须说,这是一个非常典型的 `margin` 应用,虽然如今看起来貌似使用场景不是太大,但还是好多人喜欢在面试时对人问起,我偶尔也会,但不多。\n\n假设一个宽300px,高300px的盒子要在整个页面中水平垂直居中,我们可以这样做:\n\n### HTML\n\n <div id=\"demo\">这是一个水平垂直居中的容器</div>\n\n### CSS\n\n #demo{\n position:absolute;\n top:50%;\n left:50%;\n width:300px;\n height:300px;\n margin-top:-150px;\n margin-left:-150px;\n }\n\n恩,是的,借助绝对定位。我们先来看看 `DEMO2`:[margin实现已知宽高元素水平垂直居中](http://demo.doyoe.com/css/margin/alignment.htm)\n\n先通过 `top/left` 将 `#demo` 的绝对定位流起始位置设置为当前屏的中心点,此时 `#demo` 的左上角这个点其实已经是相对于页面水平垂直居中了,由于它的宽度和高度都是300px,所以从起始位置向右下各延伸300px后才是整个 `#demo` 的真正位置。此时整个 `#demo` 其实并不是水平垂直居中的,除非我们将 `#demo` 的中心点放在当前屏的中心点上。怎么做?\n\n这时我们就需要使用 `margin` 了,在 [margin系列之与相对偏移的异同](http://blog.doyoe.com/2013/12/02/css/margin系列之与相对偏移的异同/) 这篇文章里,我们就说过 `margin` 是以自身作为参照物进行位置偏移的。所以我们只需要将 `#demo` 相对自身向上偏移150px,向左偏移150px,就能够实现将自身的中心点放在当前屏的中心点上,也就实现了自身在当前屏的水平垂直居中。\n\n为什么代码里是 `-150px` ?好吧,如果用 `margin-top` 来实现向上偏移,必须是负值,不是么?如果是正值的话,就是向下偏移了,其实也相当于是 `margin-bottom` 的正值, `margin-left` 亦然,我们在 [margin系列之与相对偏移的异同](http://blog.doyoe.com/2013/12/02/css/margin系列之与相对偏移的异同/) 文章最后同样说过这个。基础知识很重要,有木有?\n\n## tabstrip底边线重合\n\n先上个需求,如 `图二`:\n\n![tabstrip底边线重合](http://demo.doyoe.com/css/margin/images/tab.png)(图二)\n\n看到 `图二` ,我想大家可能知道可能知道要做什么了。\n\n对,我们要做的就是 tab 项与底边线重合,这应该是我们常见的场景了,`margin` 仍然是最佳选择。先来看代码:\n\n### HTML\n\n <div id=\"demo\">\n <a href=\"?\">分类一</a>\n <a href=\"?\" class=\"on\">分类二</a>\n <a href=\"?\">分类三</a>\n <a href=\"?\">分类四</a>\n </div>\n\n### CSS\n\n #demo{\n border-bottom:1px solid #aaa;\n }\n #demo a{\n display:inline-block;\n margin-bottom:-1px;\n border:1px solid #aaa;\n }\n #demo .on{\n border-bottom-color:#fff;\n }\n\n要实现 `tab` 中各项与包含块的底边线重合,重点在于将包含块的底边线向上偏移1px,这样就与 `tab` 各项的底部重合在一起。\n\n怎样可以做到让包含块底边线向上偏移1px?恩,`margin` 是那么的顺其自然。我们只需要将 `tab` 各项的 `margin-bottom` 设置为 -1px 即可,其本身高度不变,但包含块底部会向上1px。\n\n来看看具体实现的例子 `DEMO3`:[tabstrip底边线重合](http://demo.doyoe.com/css/margin/tab.htm)\n\n## 双重边线\n\n实际场景可能比这会稍复杂一些,我们看个大概即可,主要是拓宽一下思路,来看 `图三`:\n\n![多重边线](http://demo.doyoe.com/css/margin/images/double-lines.png)(图三)\n\n从图三中,我们可以看到每行都会有一个双色的边线,这就是我们要做的,HTML代码大约是这样:\n\n### HTML\n\n <div id=\"demo\">\n <ul>\n <li>这是一个双重边线的示例</li>\n <li>这是一个双重边线的示例</li>\n <li>这是一个双重边线的示例</li>\n <li>这是一个双重边线的示例</li>\n </ul>\n </div>\n\n怎么做?恩,我们可以用常规的方式来解决,比如完全使用 `border` :\n\n### CSS Case1\n\n #demo li{\n border-top:1px solid #fff;\n border-bottom:1px solid #ccc;\n }\n\n结果出来后,我们会发现最顶部多出了一条线,同时最底部又少了一条线。当然,这都可以被解决,我们可以让 `ul` 来辅助完成,例如让其 负margin-top + border-bottom,不过如果 `ul` 或者其父元素有垂直方向 `padding` 的话,处理起来可能会稍显蛋疼。\n\n还有其他解?当然,会有的,来看:\n\n### CSS Case2\n\n #demo ul{\n overflow:hidden;\n background:#fff;\n }\n #demo li{\n margin-bottom:1px;\n border-bottom:1px solid #ccc;\n background:#eee;\n }\n\n是的,选择 `margin` 作为实现手段。以 `ul` 的底色配合 `margin` 模拟出线条的外观,这其实也挺讨人喜欢的,不是么?看具体实现 `DEMO4`:[双重边线](http://demo.doyoe.com/css/margin/double-lines.htm)\n\n`margin` 模拟边线还可以做什么?比如做个表格神马的,看看 `DEMO5`:[margin模拟表格边线](http://demo.doyoe.com/css/margin/table.htm)\n\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","source":"_posts/css/margin系列之内秀篇(二).md","raw":"title: margin系列之内秀篇(二)\ndate: 2013-12-14 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [margin, w3c, margin应用]\n---\n\n## 可挖掘性\n\n之前已经写过一篇关于 `margin` 应用场景的文章:[margin系列之内秀篇](http://blog.doyoe.com/2013/12/06/css/margin系列之内秀篇/),当然,它的应用场景会远大于文中所述,无法一一列举。\n\n所以本篇权当是对此的补遗好了,各位客官如有比较Cool的想法都可以留言给我,我会视情况补丁进来。\n\n## 1像素圆角\n\n<!--more-->\n\n这有什么好聊的吗?`border-radius` 瞬间可将之秒杀。恩,有的时候你不得不承认CSS3真是一把大杀器。不过当年我们是怎么做的?(会暴露年龄么?)\n\n先看看我们要做什么,`图一`:\n\n![1px圆角](http://demo.doyoe.com/css/margin/images/radius.png)(图一)\n\n如上图一,我们会这样写:\n\n### HTML\n\n <div id=\"demo\">\n <a href=\"?\"><span>1px圆角</span></a>\n <a href=\"?\"><span>确定</span></a>\n <a href=\"?\"><span>取消</span></a>\n </div>\n\n### CSS\n\n #demo a,#demo span{\n display:inline-block;\n vertical-align:top;\n }\n #demo span{\n margin:1px -1px; /* 关键规则 */\n }\n\n一条CSS规则我们就可以实现1px圆角,你信吗?来看`DEMO1`:[margin实现1px圆角](http://demo.doyoe.com/css/margin/radius.htm)\n\n看到`DEMO1`的结果后,你会发现我们确实做到了1px圆角,很简单,有木有?在没有 `border-radius` 的年代,我们也很欢乐。\n\n看到Code后,我想应该不用太解释为什么可以实现?\n\nBTW,多像素圆角也可以参考这种方式来实现,如果你实在不想用图片的话。\n\n## 已知宽高元素水平垂直居中\n\n必须说,这是一个非常典型的 `margin` 应用,虽然如今看起来貌似使用场景不是太大,但还是好多人喜欢在面试时对人问起,我偶尔也会,但不多。\n\n假设一个宽300px,高300px的盒子要在整个页面中水平垂直居中,我们可以这样做:\n\n### HTML\n\n <div id=\"demo\">这是一个水平垂直居中的容器</div>\n\n### CSS\n\n #demo{\n position:absolute;\n top:50%;\n left:50%;\n width:300px;\n height:300px;\n margin-top:-150px;\n margin-left:-150px;\n }\n\n恩,是的,借助绝对定位。我们先来看看 `DEMO2`:[margin实现已知宽高元素水平垂直居中](http://demo.doyoe.com/css/margin/alignment.htm)\n\n先通过 `top/left` 将 `#demo` 的绝对定位流起始位置设置为当前屏的中心点,此时 `#demo` 的左上角这个点其实已经是相对于页面水平垂直居中了,由于它的宽度和高度都是300px,所以从起始位置向右下各延伸300px后才是整个 `#demo` 的真正位置。此时整个 `#demo` 其实并不是水平垂直居中的,除非我们将 `#demo` 的中心点放在当前屏的中心点上。怎么做?\n\n这时我们就需要使用 `margin` 了,在 [margin系列之与相对偏移的异同](http://blog.doyoe.com/2013/12/02/css/margin系列之与相对偏移的异同/) 这篇文章里,我们就说过 `margin` 是以自身作为参照物进行位置偏移的。所以我们只需要将 `#demo` 相对自身向上偏移150px,向左偏移150px,就能够实现将自身的中心点放在当前屏的中心点上,也就实现了自身在当前屏的水平垂直居中。\n\n为什么代码里是 `-150px` ?好吧,如果用 `margin-top` 来实现向上偏移,必须是负值,不是么?如果是正值的话,就是向下偏移了,其实也相当于是 `margin-bottom` 的正值, `margin-left` 亦然,我们在 [margin系列之与相对偏移的异同](http://blog.doyoe.com/2013/12/02/css/margin系列之与相对偏移的异同/) 文章最后同样说过这个。基础知识很重要,有木有?\n\n## tabstrip底边线重合\n\n先上个需求,如 `图二`:\n\n![tabstrip底边线重合](http://demo.doyoe.com/css/margin/images/tab.png)(图二)\n\n看到 `图二` ,我想大家可能知道可能知道要做什么了。\n\n对,我们要做的就是 tab 项与底边线重合,这应该是我们常见的场景了,`margin` 仍然是最佳选择。先来看代码:\n\n### HTML\n\n <div id=\"demo\">\n <a href=\"?\">分类一</a>\n <a href=\"?\" class=\"on\">分类二</a>\n <a href=\"?\">分类三</a>\n <a href=\"?\">分类四</a>\n </div>\n\n### CSS\n\n #demo{\n border-bottom:1px solid #aaa;\n }\n #demo a{\n display:inline-block;\n margin-bottom:-1px;\n border:1px solid #aaa;\n }\n #demo .on{\n border-bottom-color:#fff;\n }\n\n要实现 `tab` 中各项与包含块的底边线重合,重点在于将包含块的底边线向上偏移1px,这样就与 `tab` 各项的底部重合在一起。\n\n怎样可以做到让包含块底边线向上偏移1px?恩,`margin` 是那么的顺其自然。我们只需要将 `tab` 各项的 `margin-bottom` 设置为 -1px 即可,其本身高度不变,但包含块底部会向上1px。\n\n来看看具体实现的例子 `DEMO3`:[tabstrip底边线重合](http://demo.doyoe.com/css/margin/tab.htm)\n\n## 双重边线\n\n实际场景可能比这会稍复杂一些,我们看个大概即可,主要是拓宽一下思路,来看 `图三`:\n\n![多重边线](http://demo.doyoe.com/css/margin/images/double-lines.png)(图三)\n\n从图三中,我们可以看到每行都会有一个双色的边线,这就是我们要做的,HTML代码大约是这样:\n\n### HTML\n\n <div id=\"demo\">\n <ul>\n <li>这是一个双重边线的示例</li>\n <li>这是一个双重边线的示例</li>\n <li>这是一个双重边线的示例</li>\n <li>这是一个双重边线的示例</li>\n </ul>\n </div>\n\n怎么做?恩,我们可以用常规的方式来解决,比如完全使用 `border` :\n\n### CSS Case1\n\n #demo li{\n border-top:1px solid #fff;\n border-bottom:1px solid #ccc;\n }\n\n结果出来后,我们会发现最顶部多出了一条线,同时最底部又少了一条线。当然,这都可以被解决,我们可以让 `ul` 来辅助完成,例如让其 负margin-top + border-bottom,不过如果 `ul` 或者其父元素有垂直方向 `padding` 的话,处理起来可能会稍显蛋疼。\n\n还有其他解?当然,会有的,来看:\n\n### CSS Case2\n\n #demo ul{\n overflow:hidden;\n background:#fff;\n }\n #demo li{\n margin-bottom:1px;\n border-bottom:1px solid #ccc;\n background:#eee;\n }\n\n是的,选择 `margin` 作为实现手段。以 `ul` 的底色配合 `margin` 模拟出线条的外观,这其实也挺讨人喜欢的,不是么?看具体实现 `DEMO4`:[双重边线](http://demo.doyoe.com/css/margin/double-lines.htm)\n\n`margin` 模拟边线还可以做什么?比如做个表格神马的,看看 `DEMO5`:[margin模拟表格边线](http://demo.doyoe.com/css/margin/table.htm)\n\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","slug":"css/margin系列之内秀篇(二)","published":1,"updated":"2016-04-12T08:29:20.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvago00292ypkgmxah41e"},{"title":"margin系列之内秀篇","date":"2013-12-06T03:15:00.000Z","author":"杜瑶","_content":"\n## 最Cool的利器\n\n一样东西在不同的场景,不同的人手里,所能做的事会有很大不同。我深切的以为 `margin` 绝对是 CSS 中最有能力的利器之一,不知大家以为然否?\n\n前面几篇文章大概的讲了一些关于 `margin` 的特性,所以本篇会聊聊 `margin` 的实际应用场景,也算让自己休息一下,不用再讲知识点。\n\n## 有个很典型的需求\n\n<!--more-->\n\n相信接下来这个需求,你十有八九实现过,甚至实现过多次,来看 `图一`:\n\n![经典文本标题列表](http://demo.doyoe.com/css/margin/images/text-list.png)\n\n我们看到这个图中,有个列表,每个列表项下面都有一条线,但最后一项没有。我们预期的代码是:\n\n <div id=\"demo\">\n <h3>标题列表</h3>\n <ul>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n </ul>\n </div>\n\n如果每项都有条底线,我们可以很简单的做到,如下:\n\n #demo li{\n border-bottom: 1px solid #ccc;\n }\n\n然而为了处理最后一项,事情就变得有点纠结了。我知道肯定有人要说,我们有 `:first-child`, `:nth-last-child(n)`, `:nth-last-of-type(n)` 之类的CSS3选择符,要处理这个,太easy了。恩,我也不得不承认,CSS3确认让事情变得简单多了。但我们可能需要面对一些国情,因为需要照顾一些弱小者,比如IE6-8,它们离CSS3的世界太远。\n\n## 传说中的first/last解决方案\n\n所以我们需要找别的方法,于是这样的代码,相信你见过无数遍了:\n\n <div id=\"demo\">\n <h3>标题列表</h3>\n <ul>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li class=\"last\">» 有点累想歇一下好长一个标题</li>\n </ul>\n </div>\n\n我没乱说,你肯定见到类似的代码千百遍了?是的,它确实能够解决我们的问题,请看 `DEMO1` [传说中的first/last解决方案](http://demo.doyoe.com/css/margin/text-list-add-class-solution.htm),代码如下:\n\n\t#demo .last{\n border-bottom: 0 none;\n }\n\n使用特殊的class来单独处理这项,但我不是很喜欢这样的code,原因大致有:\n\n* 需单独定义一个差异化的class;\n* 不利于数据循环输出,因为还得判断是否最后一项;\n\n## margin的神来之笔\n\n基于以上的原因,肯定会有其它的解决方案出现,这时margin无疑是非常不错的选择,来看代码:\n\n\t#demo{\n overflow:hidden;\n }\n #demo ul{\n margin-bottom: -1px;\n }\n\nCSS代码如上,HTML代码当时使用开篇时的那段,结果请看:`DEMO2` [margin解决方案](http://demo.doyoe.com/css/margin/text-list.htm)\n\n是不是很Cool,完全避免了上述的问题,并且代码量很小。至于为什么可以这样实现,前几篇文章里有说过,margin是互动的,能影响其上下文的布局。本例中,当 `ul margin-bottom:-1px` ,其本身的高并不会被改变,但其相邻的元素则会往上 `1px` ,这时相邻的元素即其包含块 #demo,所以给 `#demo overflow:hidden` ,就直接将那 1px 的边框给裁剪掉了。\n\n## 再来个相似的需求\n\n看看下述的 `图二`,这应该也是一种非常常见的图片列表需求:\n\n![经典图片列表](http://demo.doyoe.com/css/margin/images/img-list.png)\n\n只关注图片之间的间隙,我们发现3张图片,却只有2个间隙。不论你是用 `margin-left` 或者说是 `margin-right` ,都无法直接达成这个需求。\n\n当然,可以像 `DEMO1` 那样给第一个或者最后一个添加一个特殊类 first/last 来解决。但这种方式刚被说不喜欢,所以想想用 `margin` 方式吧,思路应该说是和 `DEMO2` 毫无二致。来看代码:\n\n### CSS\n\n\t#demo{\n overflow:hidden;\n }\n #demo ul{\n margin-right:-10px;\n }\n\n### HTML\n\n <div id=\"demo\">\n <h3>图片列表</h3>\n\t\t<ul>\n <li><img src=\"images/1.jpg\" alt=\"\" /></li>\n <li><img src=\"images/2.jpg\" alt=\"\" /></li>\n <li><img src=\"images/1.jpg\" alt=\"\" /></li>\n </ul>\n </div>\n\n恩,就这么简单,很美妙。效果可移步 `DEMO3` [margin处理图片列表间隙解决方案](http://demo.doyoe.com/css/margin/img-list.htm)\n\n我知道不少人还会使用给图片列表容器加宽度的方式来进行处理,当然,它很OK,不过不够灵活,因为在不同场景下,宽度可能不一样,这样的code无法被提取为公用样式,复用性不强。\n\n而 `margin` 的方式完全不care几乎任何场景,都可以使用,因为在大多数情况,我们这样一个图片模块都是自适应宽度的,因为它会处于某个layout下,宽度完全取决于layout,所以其实在真实场景下 #demo 的 `overflow` 并不是必须的,也就是说 `margin-right` 的负值理论上可以预设成一个很大的值。\n\n### CSS\n\n #demo ul{\n margin-right:-100px; /* 这个可以设置得比li的间隙更大,所以理论上可以写一次而适用于真实场景的任何情况 */\n }\n\n看我们简单还原的真实场景使用方式:`DEMO4` [模拟真实场景:margin处理图片列表间隙解决方案](http://demo.doyoe.com/css/margin/img-list-2.htm)。恩,就这样,灵活性和可扩展性爆棚,不是么?\n\n## 缩进实例\n\n依然先贴个图,以下是 `图三`:\n\n![文本缩进](http://demo.doyoe.com/css/margin/images/indent.png)\n\n貌似是个好常见的需求场景,当然,要实现这样的效果,对于大家来说都不过是信手拈来,再容易不过。\n\n### HTML\n\n <div>\n <strong>简介:</strong>\n <p>该写点什么好呢?好头痛,一个能把value念成“哇柳”的中老年人,猛然觉得没文化好可怕。</p>\n </div>\n\n你可能随手就会写下 `float + margin/padding`,`float + bfc`,`absolute + margin/padding`,`flex` 等方案中的随意一个,恩,都很Cool,我也常这么干。\n\n只是有的时候在一个小场景下,希望能比较轻量的出来这样的缩进,可能不想有浮动,绝对定位,清除浮动之类的,怎么破?\n\n## margin依然是你很好的选择\n\n你想到了吗?是的,用margin。\n\n### HTML\n\n <p><strong>简介:</strong>该写点什么好呢?好头痛,一个能把value念成“哇柳”的中老年人,猛然觉得没文化好可怕。</p>\n\n### CSS\n\n p{\n padding-left:45px;\n }\n strong{\n margin-left:-45px;\n }\n\n\n看起来很简单,没有浮动,没有绝对定位,没有其它重布局,很清凉有木有?\n\n甚至 `HTML` 也可以更简单,因为无需对后面那长段做任何处理,所以不需要再加包裹。来看看具体例子吧。`DEMO5` [margin缩进实例](http://demo.doyoe.com/css/margin/indent.htm)。我想这样的轻量方式,在一定时候还是有使用价值的,不是么?\n\n## 视觉欺骗伪等高\n\n等高布局在一段时间内好似挺火,方案也涌现过不少,如 `图四`:\n\n![等高布局](http://demo.doyoe.com/css/margin/images/layout.png)\n\n该图要求,不论是主栏还是侧栏,总是以最高的那列为基准高度。核心代码:\n\n### CSS\n\n #doc{\n overflow:hidden;\n }\n #main,#aside{\n margin-bottom:-999px;\n padding-bottom:999px;\n }\n\n### HTML\n\n <div id=\"doc\">\n <div id=\"main\">主内容栏<br />占位内容</div>\n <div id=\"aside\">侧边栏</div>\n </div>\n\n先看看结果:`DEMO6` [margin伪等高布局](http://demo.doyoe.com/css/margin/layout.htm)\n\n效果和我们的要求一致,达到了等高布局。需要提醒的是,这其实只是视觉欺骗,做到的了伪高等高。主栏和侧栏的实际高度其实并不相等,之所以可以达成这样的效果,其原因在于负 `margin` 值。我们前文中有提到过,`margin` 会影响其上下文布局,当我们将 `margin-bottom` 设置为负值时,其相邻的包含块元素,底部会自动上去其负值的高度,直到最高的那列底部边缘为止,然后裁剪。但该列本身的高度并不会发生变化,同时因为有 `padding-bottom` 向下扩展,颜色被填充满padding区域,于是达到视觉上的等高。\n\n描述的貌似有点复杂,没文化好可怕。差不多就这样,不能接着往下写了,要不收不住。\n\n作为 CSS 的重要属性 `margin` 有很多可被挖掘的潜力,需要更多的是想法。enjoy it.\n\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","source":"_posts/css/margin系列之内秀篇.md","raw":"title: margin系列之内秀篇\ndate: 2013-12-06 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [margin, w3c, margin应用]\n---\n\n## 最Cool的利器\n\n一样东西在不同的场景,不同的人手里,所能做的事会有很大不同。我深切的以为 `margin` 绝对是 CSS 中最有能力的利器之一,不知大家以为然否?\n\n前面几篇文章大概的讲了一些关于 `margin` 的特性,所以本篇会聊聊 `margin` 的实际应用场景,也算让自己休息一下,不用再讲知识点。\n\n## 有个很典型的需求\n\n<!--more-->\n\n相信接下来这个需求,你十有八九实现过,甚至实现过多次,来看 `图一`:\n\n![经典文本标题列表](http://demo.doyoe.com/css/margin/images/text-list.png)\n\n我们看到这个图中,有个列表,每个列表项下面都有一条线,但最后一项没有。我们预期的代码是:\n\n <div id=\"demo\">\n <h3>标题列表</h3>\n <ul>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n </ul>\n </div>\n\n如果每项都有条底线,我们可以很简单的做到,如下:\n\n #demo li{\n border-bottom: 1px solid #ccc;\n }\n\n然而为了处理最后一项,事情就变得有点纠结了。我知道肯定有人要说,我们有 `:first-child`, `:nth-last-child(n)`, `:nth-last-of-type(n)` 之类的CSS3选择符,要处理这个,太easy了。恩,我也不得不承认,CSS3确认让事情变得简单多了。但我们可能需要面对一些国情,因为需要照顾一些弱小者,比如IE6-8,它们离CSS3的世界太远。\n\n## 传说中的first/last解决方案\n\n所以我们需要找别的方法,于是这样的代码,相信你见过无数遍了:\n\n <div id=\"demo\">\n <h3>标题列表</h3>\n <ul>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li>» 有点累想歇一下好长一个标题</li>\n <li class=\"last\">» 有点累想歇一下好长一个标题</li>\n </ul>\n </div>\n\n我没乱说,你肯定见到类似的代码千百遍了?是的,它确实能够解决我们的问题,请看 `DEMO1` [传说中的first/last解决方案](http://demo.doyoe.com/css/margin/text-list-add-class-solution.htm),代码如下:\n\n\t#demo .last{\n border-bottom: 0 none;\n }\n\n使用特殊的class来单独处理这项,但我不是很喜欢这样的code,原因大致有:\n\n* 需单独定义一个差异化的class;\n* 不利于数据循环输出,因为还得判断是否最后一项;\n\n## margin的神来之笔\n\n基于以上的原因,肯定会有其它的解决方案出现,这时margin无疑是非常不错的选择,来看代码:\n\n\t#demo{\n overflow:hidden;\n }\n #demo ul{\n margin-bottom: -1px;\n }\n\nCSS代码如上,HTML代码当时使用开篇时的那段,结果请看:`DEMO2` [margin解决方案](http://demo.doyoe.com/css/margin/text-list.htm)\n\n是不是很Cool,完全避免了上述的问题,并且代码量很小。至于为什么可以这样实现,前几篇文章里有说过,margin是互动的,能影响其上下文的布局。本例中,当 `ul margin-bottom:-1px` ,其本身的高并不会被改变,但其相邻的元素则会往上 `1px` ,这时相邻的元素即其包含块 #demo,所以给 `#demo overflow:hidden` ,就直接将那 1px 的边框给裁剪掉了。\n\n## 再来个相似的需求\n\n看看下述的 `图二`,这应该也是一种非常常见的图片列表需求:\n\n![经典图片列表](http://demo.doyoe.com/css/margin/images/img-list.png)\n\n只关注图片之间的间隙,我们发现3张图片,却只有2个间隙。不论你是用 `margin-left` 或者说是 `margin-right` ,都无法直接达成这个需求。\n\n当然,可以像 `DEMO1` 那样给第一个或者最后一个添加一个特殊类 first/last 来解决。但这种方式刚被说不喜欢,所以想想用 `margin` 方式吧,思路应该说是和 `DEMO2` 毫无二致。来看代码:\n\n### CSS\n\n\t#demo{\n overflow:hidden;\n }\n #demo ul{\n margin-right:-10px;\n }\n\n### HTML\n\n <div id=\"demo\">\n <h3>图片列表</h3>\n\t\t<ul>\n <li><img src=\"images/1.jpg\" alt=\"\" /></li>\n <li><img src=\"images/2.jpg\" alt=\"\" /></li>\n <li><img src=\"images/1.jpg\" alt=\"\" /></li>\n </ul>\n </div>\n\n恩,就这么简单,很美妙。效果可移步 `DEMO3` [margin处理图片列表间隙解决方案](http://demo.doyoe.com/css/margin/img-list.htm)\n\n我知道不少人还会使用给图片列表容器加宽度的方式来进行处理,当然,它很OK,不过不够灵活,因为在不同场景下,宽度可能不一样,这样的code无法被提取为公用样式,复用性不强。\n\n而 `margin` 的方式完全不care几乎任何场景,都可以使用,因为在大多数情况,我们这样一个图片模块都是自适应宽度的,因为它会处于某个layout下,宽度完全取决于layout,所以其实在真实场景下 #demo 的 `overflow` 并不是必须的,也就是说 `margin-right` 的负值理论上可以预设成一个很大的值。\n\n### CSS\n\n #demo ul{\n margin-right:-100px; /* 这个可以设置得比li的间隙更大,所以理论上可以写一次而适用于真实场景的任何情况 */\n }\n\n看我们简单还原的真实场景使用方式:`DEMO4` [模拟真实场景:margin处理图片列表间隙解决方案](http://demo.doyoe.com/css/margin/img-list-2.htm)。恩,就这样,灵活性和可扩展性爆棚,不是么?\n\n## 缩进实例\n\n依然先贴个图,以下是 `图三`:\n\n![文本缩进](http://demo.doyoe.com/css/margin/images/indent.png)\n\n貌似是个好常见的需求场景,当然,要实现这样的效果,对于大家来说都不过是信手拈来,再容易不过。\n\n### HTML\n\n <div>\n <strong>简介:</strong>\n <p>该写点什么好呢?好头痛,一个能把value念成“哇柳”的中老年人,猛然觉得没文化好可怕。</p>\n </div>\n\n你可能随手就会写下 `float + margin/padding`,`float + bfc`,`absolute + margin/padding`,`flex` 等方案中的随意一个,恩,都很Cool,我也常这么干。\n\n只是有的时候在一个小场景下,希望能比较轻量的出来这样的缩进,可能不想有浮动,绝对定位,清除浮动之类的,怎么破?\n\n## margin依然是你很好的选择\n\n你想到了吗?是的,用margin。\n\n### HTML\n\n <p><strong>简介:</strong>该写点什么好呢?好头痛,一个能把value念成“哇柳”的中老年人,猛然觉得没文化好可怕。</p>\n\n### CSS\n\n p{\n padding-left:45px;\n }\n strong{\n margin-left:-45px;\n }\n\n\n看起来很简单,没有浮动,没有绝对定位,没有其它重布局,很清凉有木有?\n\n甚至 `HTML` 也可以更简单,因为无需对后面那长段做任何处理,所以不需要再加包裹。来看看具体例子吧。`DEMO5` [margin缩进实例](http://demo.doyoe.com/css/margin/indent.htm)。我想这样的轻量方式,在一定时候还是有使用价值的,不是么?\n\n## 视觉欺骗伪等高\n\n等高布局在一段时间内好似挺火,方案也涌现过不少,如 `图四`:\n\n![等高布局](http://demo.doyoe.com/css/margin/images/layout.png)\n\n该图要求,不论是主栏还是侧栏,总是以最高的那列为基准高度。核心代码:\n\n### CSS\n\n #doc{\n overflow:hidden;\n }\n #main,#aside{\n margin-bottom:-999px;\n padding-bottom:999px;\n }\n\n### HTML\n\n <div id=\"doc\">\n <div id=\"main\">主内容栏<br />占位内容</div>\n <div id=\"aside\">侧边栏</div>\n </div>\n\n先看看结果:`DEMO6` [margin伪等高布局](http://demo.doyoe.com/css/margin/layout.htm)\n\n效果和我们的要求一致,达到了等高布局。需要提醒的是,这其实只是视觉欺骗,做到的了伪高等高。主栏和侧栏的实际高度其实并不相等,之所以可以达成这样的效果,其原因在于负 `margin` 值。我们前文中有提到过,`margin` 会影响其上下文布局,当我们将 `margin-bottom` 设置为负值时,其相邻的包含块元素,底部会自动上去其负值的高度,直到最高的那列底部边缘为止,然后裁剪。但该列本身的高度并不会发生变化,同时因为有 `padding-bottom` 向下扩展,颜色被填充满padding区域,于是达到视觉上的等高。\n\n描述的貌似有点复杂,没文化好可怕。差不多就这样,不能接着往下写了,要不收不住。\n\n作为 CSS 的重要属性 `margin` 有很多可被挖掘的潜力,需要更多的是想法。enjoy it.\n\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","slug":"css/margin系列之内秀篇","published":1,"updated":"2016-03-29T02:40:23.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvagr002f2ypk7x2e9sgr"},{"title":"margin系列之与相对偏移的异同","date":"2013-12-02T03:15:00.000Z","author":"杜瑶","_content":"\n## 也许我们是一样的\n\n可能大家都用会 `margin` 或者相对偏移的 `top, right, bottom, left` 来做一些类似元素偏移的事,其实我也会。这回我们只聊 `relative` 下的 `top, right, bottom, left` 。\n\n比如说我们想让一个 div 向下偏移 50 个像素,通常会这样:\n\n### Case 1:\n\n```css\n#demo .margin-top{\n\tmargin-top: 50px;\n}\n```\n\n### Case 2:\n\n```css\n#demo .relative-top{\n\tposition:relative;\n\ttop: 50px;\n}\n```\n\n### HTML:\n```HTML\n<div id=\"demo\">\n\t<div class=\"margin-top\">我是margin-top:50px</div>\n\t<div class=\"relative-top\">我是relative top:50px</div>\n</div>\n```\n\n上述2种方式,我们都可以完成 div 向下偏移 50 个像素的需求。来看看 `DEMO1`: [margin-top vs. relative top](http://demo.doyoe.com/css/margin/margin-top-vs-relative-top.htm)\n\n<!--more-->\n\n## 其实它们真的有相似的地方\n\n从上面的例子,可以发现不论是 `margin-top` 还是 `relative top` 都是以自身作为参照物进行偏移的。\n\n顺带说一下 `absolute` 偏移相对的是包含块,并且其偏移值是从包含块的 `padding` 区域开始计算。\n\n## 但它们真的不一样,我们来看看规范怎么说:\n\n### margin:\n> 原文:Margins in CSS serve to add both horizontal and vertical space between boxes.\n\n> 翻译:CSS中的margin用来添加盒子之间的水平和垂直间隙。\n\n### top, right, bottom, left:\n> 原文:An element is said to be positioned if its ‘position’ property has a value other than ‘static’. Positioned elements generate positioned boxes, and may be laid out according to the following four physical properties: top, right, bottom, left.\n\n> 翻译:一个元素的position属性值如果不为static则发生定位。定位元素会产生定位盒,并且会根据 top, right, bottom, left 这4个物理属性进行排版布局。\n\n意思很明白,`margin` 是用来增加自身与它人之间的空白,而 `top, right, bottom, left` 是用来对自身进行排版,作用完全不同。\n\n也就是说 `margin` 是互动的,因为它要影响它人;而 `top, right, bottom, left `是孤独的,它只是自己一个人玩,不影响它人。\n\n## 回到之前那个例子\n在 `DEMO1` 中,我们看到2个方法都可以做到向下偏移50px,不过它们的意义不太一样。\n\nmargin的case: 让该div的顶部与其相邻的元素(这里即其包含块)留有50px的空白。\n\ntop的case: 让该div距离其包含块顶部边缘50px,因为是 `relative` ,所以这里是距离div自己的顶部边缘。\n\n## 我们大胆假设一下\n如果我们设置 `margin-bottom` 和 `bottom` 的值也为50px,它们的表现将完全不一样,你觉得呢? 恩,试试:\n\n### Case 1:\n\n```css\n#demo .margin-bottom{\n\tmargin-bottom: 50px;\n}\n```\n\n### Case 2:\n\n```css\n#demo .relative-bottom{\n\tposition: relative;\n\tbottom: 50px;\n}\n```\n\n### HTML:\n```HTML\n<div id=\"demo\">\n\t<p class=\"margin-bottom\">我是margin-bottom:50px</p>\n\t<p class=\"relative-bottom\">我是relative bottom:50px</p>\n</div>\n```\n\n验证猜想的时刻到了,来看看 `DEMO2`: [对margin-bottom和bottom的表现猜想](http://demo.doyoe.com/css/margin/margin-bottom-vs-relative-bottom.htm)\n\n结果有出乎你的意料吗?好吧,不论怎么,解释下为什么会这样?\n\n前面我们说过 `margin` 是用来增加自身与它人之间的间隙,所以它距包含块底部有50px,这应该能理解?那为什么 `bottom`会跑到上面去?相信仔细看了之前的描述,你应该知道。因为它要相对自己的底部边缘有50px,恩,不是-50px,所以它等于是向上偏移了50px,很简单,不是吗?\n\n还有一个细节你注意到了吗?`bottom` 没有撑开它的包含块,仔细看看它的包含块的背景色区域。这正好也验证了之前说的 `top, right, bottom, left` 是孤独的,它只是自己一个人玩,不影响它人。\n\n## 孤独患者\n我们将 `DEMO1` 稍改改,为其加上一点上下文,再看看结果:\n\n### Case 1:\n\n```css\n#demo .margin-top p{\n\tmargin-top: 50px;\n}\n```\n\n### Case 2:\n\n```css\n#demo .relative-top p{\n\tposition:relative;\n\ttop: 50px;\n}\n```\n\n### HTML:\n```HTML\n<div id=\"demo\">\n\t<div class=\"margin-top\">\n\t\t<p>我是margin-top:50px</p>\n\t\t我是一段随便什么上下文\n\t</div>\n\t<div class=\"relative-top\">\n\t\t<p>我是relative top:50px</p>\n\t\t我是一段随便什么上下文\n\t</div>\n</div>\n```\n\n迫不及待的要看看实际例子了,不是么?`DEMO3`: [再次验证一下top, right, bottom, left是孤独患者](http://demo.doyoe.com/css/margin/margin-top-vs-relative-top-2.htm)\n\n至此可以再次说明 `top, right, bottom, left` 真的和其上下文一毛钱关系都没有,绝对的孤单患者。\n\n所以 `margin` 和 `top, right, bottom, left ` 分别要在什么场景使用,应该可以有考量的依据了,不是么?enjoy it.\n\n## 似乎还漏了点啥\n差点就这么结篇了,想起还有点遗漏的地方。\n\n当position为relative时,如果top和bottom都是auto,则它们的计算值是0,right和left亦然;如果top和bottom其中一个为auto,则auto相当于另一个的负值,即top = -bottom,right和left亦然;如果top和bottom的值都不为auto,则忽略bottom,如果right和left的值都不为auto,则忽略right。\n\n好吧,不得不再写个例子:`DEMO4`: [top, right, bottom, left详述](http://demo.doyoe.com/css/margin/top-right-bottom-left.htm)\n\n至于margin,就留给大家思考一下也不错 ^_^\n\nenjoy it again.\n\n## 可参考:\n\n* http://dev.w3.org/csswg/css-box/#the-margin-properties\n* http://dev.w3.org/csswg/css-position/#box-offsets-trbl\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","source":"_posts/css/margin系列之与相对偏移的异同.md","raw":"title: margin系列之与相对偏移的异同\ndate: 2013-12-02 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [margin, w3c, margin偏移]\n---\n\n## 也许我们是一样的\n\n可能大家都用会 `margin` 或者相对偏移的 `top, right, bottom, left` 来做一些类似元素偏移的事,其实我也会。这回我们只聊 `relative` 下的 `top, right, bottom, left` 。\n\n比如说我们想让一个 div 向下偏移 50 个像素,通常会这样:\n\n### Case 1:\n\n```css\n#demo .margin-top{\n\tmargin-top: 50px;\n}\n```\n\n### Case 2:\n\n```css\n#demo .relative-top{\n\tposition:relative;\n\ttop: 50px;\n}\n```\n\n### HTML:\n```HTML\n<div id=\"demo\">\n\t<div class=\"margin-top\">我是margin-top:50px</div>\n\t<div class=\"relative-top\">我是relative top:50px</div>\n</div>\n```\n\n上述2种方式,我们都可以完成 div 向下偏移 50 个像素的需求。来看看 `DEMO1`: [margin-top vs. relative top](http://demo.doyoe.com/css/margin/margin-top-vs-relative-top.htm)\n\n<!--more-->\n\n## 其实它们真的有相似的地方\n\n从上面的例子,可以发现不论是 `margin-top` 还是 `relative top` 都是以自身作为参照物进行偏移的。\n\n顺带说一下 `absolute` 偏移相对的是包含块,并且其偏移值是从包含块的 `padding` 区域开始计算。\n\n## 但它们真的不一样,我们来看看规范怎么说:\n\n### margin:\n> 原文:Margins in CSS serve to add both horizontal and vertical space between boxes.\n\n> 翻译:CSS中的margin用来添加盒子之间的水平和垂直间隙。\n\n### top, right, bottom, left:\n> 原文:An element is said to be positioned if its ‘position’ property has a value other than ‘static’. Positioned elements generate positioned boxes, and may be laid out according to the following four physical properties: top, right, bottom, left.\n\n> 翻译:一个元素的position属性值如果不为static则发生定位。定位元素会产生定位盒,并且会根据 top, right, bottom, left 这4个物理属性进行排版布局。\n\n意思很明白,`margin` 是用来增加自身与它人之间的空白,而 `top, right, bottom, left` 是用来对自身进行排版,作用完全不同。\n\n也就是说 `margin` 是互动的,因为它要影响它人;而 `top, right, bottom, left `是孤独的,它只是自己一个人玩,不影响它人。\n\n## 回到之前那个例子\n在 `DEMO1` 中,我们看到2个方法都可以做到向下偏移50px,不过它们的意义不太一样。\n\nmargin的case: 让该div的顶部与其相邻的元素(这里即其包含块)留有50px的空白。\n\ntop的case: 让该div距离其包含块顶部边缘50px,因为是 `relative` ,所以这里是距离div自己的顶部边缘。\n\n## 我们大胆假设一下\n如果我们设置 `margin-bottom` 和 `bottom` 的值也为50px,它们的表现将完全不一样,你觉得呢? 恩,试试:\n\n### Case 1:\n\n```css\n#demo .margin-bottom{\n\tmargin-bottom: 50px;\n}\n```\n\n### Case 2:\n\n```css\n#demo .relative-bottom{\n\tposition: relative;\n\tbottom: 50px;\n}\n```\n\n### HTML:\n```HTML\n<div id=\"demo\">\n\t<p class=\"margin-bottom\">我是margin-bottom:50px</p>\n\t<p class=\"relative-bottom\">我是relative bottom:50px</p>\n</div>\n```\n\n验证猜想的时刻到了,来看看 `DEMO2`: [对margin-bottom和bottom的表现猜想](http://demo.doyoe.com/css/margin/margin-bottom-vs-relative-bottom.htm)\n\n结果有出乎你的意料吗?好吧,不论怎么,解释下为什么会这样?\n\n前面我们说过 `margin` 是用来增加自身与它人之间的间隙,所以它距包含块底部有50px,这应该能理解?那为什么 `bottom`会跑到上面去?相信仔细看了之前的描述,你应该知道。因为它要相对自己的底部边缘有50px,恩,不是-50px,所以它等于是向上偏移了50px,很简单,不是吗?\n\n还有一个细节你注意到了吗?`bottom` 没有撑开它的包含块,仔细看看它的包含块的背景色区域。这正好也验证了之前说的 `top, right, bottom, left` 是孤独的,它只是自己一个人玩,不影响它人。\n\n## 孤独患者\n我们将 `DEMO1` 稍改改,为其加上一点上下文,再看看结果:\n\n### Case 1:\n\n```css\n#demo .margin-top p{\n\tmargin-top: 50px;\n}\n```\n\n### Case 2:\n\n```css\n#demo .relative-top p{\n\tposition:relative;\n\ttop: 50px;\n}\n```\n\n### HTML:\n```HTML\n<div id=\"demo\">\n\t<div class=\"margin-top\">\n\t\t<p>我是margin-top:50px</p>\n\t\t我是一段随便什么上下文\n\t</div>\n\t<div class=\"relative-top\">\n\t\t<p>我是relative top:50px</p>\n\t\t我是一段随便什么上下文\n\t</div>\n</div>\n```\n\n迫不及待的要看看实际例子了,不是么?`DEMO3`: [再次验证一下top, right, bottom, left是孤独患者](http://demo.doyoe.com/css/margin/margin-top-vs-relative-top-2.htm)\n\n至此可以再次说明 `top, right, bottom, left` 真的和其上下文一毛钱关系都没有,绝对的孤单患者。\n\n所以 `margin` 和 `top, right, bottom, left ` 分别要在什么场景使用,应该可以有考量的依据了,不是么?enjoy it.\n\n## 似乎还漏了点啥\n差点就这么结篇了,想起还有点遗漏的地方。\n\n当position为relative时,如果top和bottom都是auto,则它们的计算值是0,right和left亦然;如果top和bottom其中一个为auto,则auto相当于另一个的负值,即top = -bottom,right和left亦然;如果top和bottom的值都不为auto,则忽略bottom,如果right和left的值都不为auto,则忽略right。\n\n好吧,不得不再写个例子:`DEMO4`: [top, right, bottom, left详述](http://demo.doyoe.com/css/margin/top-right-bottom-left.htm)\n\n至于margin,就留给大家思考一下也不错 ^_^\n\nenjoy it again.\n\n## 可参考:\n\n* http://dev.w3.org/csswg/css-box/#the-margin-properties\n* http://dev.w3.org/csswg/css-position/#box-offsets-trbl\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","slug":"css/margin系列之与相对偏移的异同","published":1,"updated":"2016-03-29T02:40:29.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvagu002k2ypkuu7kcua5"},{"title":"margin系列之keyword auto","date":"2013-11-29T03:15:00.000Z","_content":"\n## margin的重要性:\n\n有个不容置疑的事,前端开发人员没有人能够忽视CSS `margin`的重要性。CSS coding时,margin的使用频率就如同呼吸般频繁,如果我可以说得夸张点的话。\n\nmargin作为CSS盒模型基本组成要素之一,是非常Basis的一个技术手段,所以我想对于它的一些基本情况应该不用太介绍了?\n\n## margin经常被用来做什么?\n\n* 让块元素水平居中;\n* 让元素之间留有舒适的留白;\n* 处理特殊的first或last,大家懂的?\n* 一些布局;\n\n## 需要注意的地方:\n\n* margin折叠;\n* margin的百分比值;\n* margin的auto值;\n* margin和相对偏移top, right, bottom, left的异同;\n* IE6浮动双margin Bug;\n* IE6浮动相邻元素3px Bug;\n\n看起来似乎有不少的知识点?恩,这些都是我们需要了解的,包括一些没有被列举出来的点。\n\n今天要讲的其实只是其中很少的一部分,恩,标题里有:keyword auto\n\n<!--more-->\n\n## keyword auto\n\nauto是margin的可选值之一。相信大家平时使用auto值时,最多的用法大概是 `margin: 0 auto;` 和 `margin: auto;`,恩,是的,块元素水平居中。让我们来看看代码实现:\n\n### CSS:\n\n```css\n#demo{\n\twidth: 500px;\n\tmargin: auto; /* 或者 margin: 0 auto; */\n}\n```\n\n### HTML:\n```html\n<div id=\"demo\">\n\t<p>恩,我就是那个需要水平居中的家伙。</p>\n</div>\n```\n\n为了更明显点,我们来看个例子:[margin实现块元素水平居中](//demo.doyoe.com/css/margin/horizontal-center.htm)。Cool,这么简单就实现了水平居中。\n\n不过你可能也发现了不论是 `margin: auto;` 还是 `margin: 0 auto;` 效果都是一样的,都是让 #demo 水平居中了,但纵向并没有任何变化。\n\n大家都知道 `margin` 是复合属性,也就是说 `margin: auto;` 其实相当于 `margin: auto auto auto auto;`,`margin: 0 auto;`相当于 `margin: 0 auto 0 auto;`,四个值分别对应上右下左。至于CSS中的上、右、下、左顺序就不做赘述了。\n\n根据规范,`margin-top: auto;` 和 `margin-bottom: auto;`,其计算值为0。这也就解释了为什么 `margin: auto;` 等同于 `margin: 0 auto;`。但仅此而已吗?让我们来看看规范描述:\n\n> 原文:On the A edge and C edge, the used value of ‘auto’ is 0.\n>\n> 翻译:如果场景是A和C,那么其 `auto` 计算值为 `0`。\n>\n> ![margin edge](//demo.doyoe.com/css/margin/images/margin.png)\n>\n> 更详细请参阅:[margin properties](//dev.w3.org/csswg/css-box/#the-margin-properties)\n\n由此可见,它们还与书写模式 `writing-mode` 和 文档流方向 `direction` 有关。所以我们说 `margin: auto;` 等同于 `margin: 0 auto;` 是不太精准的,因为还有前置条件。\n\n了解这些很重要,这有助于理解 `margin` 属性的设计意图。\n\nOK,聊了这么多,我们回到默认的 `writing-mode: horizontal-tb;` 和 `direction: ltr;` 的情况继续往下,后面的话题都基于这个前提。\n\n## 为什么auto能实现水平居中?\n\n这是因为水平方向的 `auto`,其计算值取决于可用空间(剩余空间)。\n\n> 原文:On the B edge and D edge, the used value depends on the available space.\n>\n> 翻译:如果场景是B和D,那么其 `auto` 计算值取决于可用空间。\n\n想象这样一个场景,一个宽100px的p被包含在一个宽500px的div内,此时设置 p 的 margin-left 值为 auto,大家觉得结果会怎样?\n\n### CSS:\n\n```css\n#demo{\n\twidth: 500px;\n}\n#demo p{\n\twidth: 100px;\n\tmargin-left: auto;\n}\n```\n\n### HTML:\n```html\n<div id=\"demo\">\n\t<p>恩,我就是那个p。</p>\n</div>\n```\n\n结果你猜到了吗?没猜到也不怕,用事实说话:[margin-left关键字auto结果猜想](//demo.doyoe.com/css/margin/margin-left-auto.htm)。\n\n好了,结果得到了,p相对于包含块右对齐了,这与规范描述一致。`margin-left:auto;` 自动占据了包含块的可用空间,即 500 - 100px = 400px。也就是说auto最后的计算值为400px,即 `margin-left:400px;`。所以 `margin-right:auto;` 的结果会相当于左对齐。\n\n到这里,相信大家都知道为什么 `margin: auto;` 和 `margin: 0 auto;` 能实现水平居中了。因为左右方向的auto值均分了可用空间,使得块元素得以在包含块内居中显示。\n\n至于垂直方向上为什么无法居中,还有更深层的原因吗?大家可以思考一下。\n\n## 可参考:\n\n* http://www.w3.org/TR/css3-box/#margins\n* http://dev.w3.org/csswg/css-box/#the-margin-properties\n* http://dev.w3.org/csswg/css-box/#Calculating\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","source":"_posts/css/margin系列之keyword auto.md","raw":"title: margin系列之keyword auto\ndate: 2013-11-29 11:15:00\ncategories: CSS\ntags: [margin, w3c]\n---\n\n## margin的重要性:\n\n有个不容置疑的事,前端开发人员没有人能够忽视CSS `margin`的重要性。CSS coding时,margin的使用频率就如同呼吸般频繁,如果我可以说得夸张点的话。\n\nmargin作为CSS盒模型基本组成要素之一,是非常Basis的一个技术手段,所以我想对于它的一些基本情况应该不用太介绍了?\n\n## margin经常被用来做什么?\n\n* 让块元素水平居中;\n* 让元素之间留有舒适的留白;\n* 处理特殊的first或last,大家懂的?\n* 一些布局;\n\n## 需要注意的地方:\n\n* margin折叠;\n* margin的百分比值;\n* margin的auto值;\n* margin和相对偏移top, right, bottom, left的异同;\n* IE6浮动双margin Bug;\n* IE6浮动相邻元素3px Bug;\n\n看起来似乎有不少的知识点?恩,这些都是我们需要了解的,包括一些没有被列举出来的点。\n\n今天要讲的其实只是其中很少的一部分,恩,标题里有:keyword auto\n\n<!--more-->\n\n## keyword auto\n\nauto是margin的可选值之一。相信大家平时使用auto值时,最多的用法大概是 `margin: 0 auto;` 和 `margin: auto;`,恩,是的,块元素水平居中。让我们来看看代码实现:\n\n### CSS:\n\n```css\n#demo{\n\twidth: 500px;\n\tmargin: auto; /* 或者 margin: 0 auto; */\n}\n```\n\n### HTML:\n```html\n<div id=\"demo\">\n\t<p>恩,我就是那个需要水平居中的家伙。</p>\n</div>\n```\n\n为了更明显点,我们来看个例子:[margin实现块元素水平居中](//demo.doyoe.com/css/margin/horizontal-center.htm)。Cool,这么简单就实现了水平居中。\n\n不过你可能也发现了不论是 `margin: auto;` 还是 `margin: 0 auto;` 效果都是一样的,都是让 #demo 水平居中了,但纵向并没有任何变化。\n\n大家都知道 `margin` 是复合属性,也就是说 `margin: auto;` 其实相当于 `margin: auto auto auto auto;`,`margin: 0 auto;`相当于 `margin: 0 auto 0 auto;`,四个值分别对应上右下左。至于CSS中的上、右、下、左顺序就不做赘述了。\n\n根据规范,`margin-top: auto;` 和 `margin-bottom: auto;`,其计算值为0。这也就解释了为什么 `margin: auto;` 等同于 `margin: 0 auto;`。但仅此而已吗?让我们来看看规范描述:\n\n> 原文:On the A edge and C edge, the used value of ‘auto’ is 0.\n>\n> 翻译:如果场景是A和C,那么其 `auto` 计算值为 `0`。\n>\n> ![margin edge](//demo.doyoe.com/css/margin/images/margin.png)\n>\n> 更详细请参阅:[margin properties](//dev.w3.org/csswg/css-box/#the-margin-properties)\n\n由此可见,它们还与书写模式 `writing-mode` 和 文档流方向 `direction` 有关。所以我们说 `margin: auto;` 等同于 `margin: 0 auto;` 是不太精准的,因为还有前置条件。\n\n了解这些很重要,这有助于理解 `margin` 属性的设计意图。\n\nOK,聊了这么多,我们回到默认的 `writing-mode: horizontal-tb;` 和 `direction: ltr;` 的情况继续往下,后面的话题都基于这个前提。\n\n## 为什么auto能实现水平居中?\n\n这是因为水平方向的 `auto`,其计算值取决于可用空间(剩余空间)。\n\n> 原文:On the B edge and D edge, the used value depends on the available space.\n>\n> 翻译:如果场景是B和D,那么其 `auto` 计算值取决于可用空间。\n\n想象这样一个场景,一个宽100px的p被包含在一个宽500px的div内,此时设置 p 的 margin-left 值为 auto,大家觉得结果会怎样?\n\n### CSS:\n\n```css\n#demo{\n\twidth: 500px;\n}\n#demo p{\n\twidth: 100px;\n\tmargin-left: auto;\n}\n```\n\n### HTML:\n```html\n<div id=\"demo\">\n\t<p>恩,我就是那个p。</p>\n</div>\n```\n\n结果你猜到了吗?没猜到也不怕,用事实说话:[margin-left关键字auto结果猜想](//demo.doyoe.com/css/margin/margin-left-auto.htm)。\n\n好了,结果得到了,p相对于包含块右对齐了,这与规范描述一致。`margin-left:auto;` 自动占据了包含块的可用空间,即 500 - 100px = 400px。也就是说auto最后的计算值为400px,即 `margin-left:400px;`。所以 `margin-right:auto;` 的结果会相当于左对齐。\n\n到这里,相信大家都知道为什么 `margin: auto;` 和 `margin: 0 auto;` 能实现水平居中了。因为左右方向的auto值均分了可用空间,使得块元素得以在包含块内居中显示。\n\n至于垂直方向上为什么无法居中,还有更深层的原因吗?大家可以思考一下。\n\n## 可参考:\n\n* http://www.w3.org/TR/css3-box/#margins\n* http://dev.w3.org/csswg/css-box/#the-margin-properties\n* http://dev.w3.org/csswg/css-box/#Calculating\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","slug":"css/margin系列之keyword auto","published":1,"updated":"2016-01-14T07:58:10.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvagw002q2ypk8thgeeu5"},{"title":"margin系列之bug巡演(二)","date":"2013-12-17T03:15:00.000Z","author":"杜瑶","_content":"\n## IE6/7 clear引发的margin-top bug\n\n我知道,这是一个被谈及较少的bug,但我几乎可以肯定你在遇见过的同时并没有把它当成是一个bug。\n\n## w3c关于 clear 特性的描述\n\n设置了 `clear` 为非 `none` 值的元素,其顶部 `border` 边界在垂直方向不允许出现在之前的浮动元素底部 `margin` 之上。\n\n<!--more-->\n\n什么意思呢?用段代码来阐述:\n\n### HTML\n\n <div class=\"a\">float:left</div>\n <div class=\"b\">clear:left</div>\n\n### CSS\n\n .a{\n float:left;\n height:30px;\n margin:20px;\n }\n .b{\n clear:left;\n height:30px;\n margin-top:-30px;\n }\n\n如上代码,你认为 `.b` 是否会相对自身向上偏移 30px 呢?然后盖住 `.a` 底部 10px?如果你真这么猜想,那就错了。\n\n来看上述代码,我们会得到什么样的结果,如 `图一`:\n\n![clear margin](http://demo.doyoe.com/css/margin/images/clear-margin.png)(图一)\n\n恩,你觉得这可能会是落后浏览器才这样,比如IE6/7。很高兴的告诉你,其实高级浏览器才这样,IE6/7的表现会是之前你猜想的那样,如下 `图二`:\n\n![clear margin](http://demo.doyoe.com/css/margin/images/clear-margin-on-ie67.png)(图二)\n\n不论你相信与否,看个例子你就明白了 `DEMO1`:[clear margin 猜想](http://demo.doyoe.com/css/margin/bug/clear-margin.html),你会发现就算将 `margin-top` 去掉,`.b` 的位置也丝毫不会改变。\n\n## 为什么会这样?\n\n我们已经说过设置了 `clear` 为非 `none` 值的元素其顶部 `border` 边界不允许出现在之前浮动元素的底部margin边界之上。也就是说必须在垂直方向上递次堆叠却不能重合。\n\n所以说高级浏览器是遵循w3c规范的,而IE6/7的实现明显有悖该规则。\n\n虽然拥有 `clear` 特性的元素其 `border` 顶部边界不允许超越之前浮动元素的底部margin边界之上,但是其margin可以和之前浮动元素的任何区域重合。我们稍微改下之前代码:\n\n### HTML\n\n <div class=\"a\">float:left</div>\n <div class=\"b\">clear:left</div>\n\n### CSS\n\n .a{\n float:left;\n height:30px;\n margin:20px;\n }\n .b{\n clear:left;\n height:30px;\n margin-top:50px;\n }\n\n我们将 `.b` 的 `margin-top` 修改为一个正值,能得到如下 `图三`:\n\n![clear margin](http://demo.doyoe.com/css/margin/images/clear-margin-2.png)(图三)\n\n图中的黄色区域是 `.b` 的 `margin-top`,你会发现,它可以和 `.a` 的任何区域重合。同时,你也可以发现 `图三` 和 `图一` 居然是一样的效果,`.b` 的实际位置都没变化过。来看例子 `DEMO2`:[clear margin 验证](http://demo.doyoe.com/css/margin/bug/clear-margin-2.html)\n\n这是否说明拥有 `clear` 特性的元素对其之前的浮动元素没有任何影响?因为不论是正值还是负值,其位置都不会发生变化。\n\n如果你这样想,那你就又错了。\n\n## 拥有clear特性的元素其margin紧邻之前的浮动元素依然有效\n\n是的,在某个临界值,这一切会发生改变,并非全然无效。\n\n这个临界值是什么?\n\n临界值是包含块内浮动元素的实际高度,即浮动元素的 margin + border + padding + height,拿我们的 `DEMO2` 来详述:\n\n`DEMO2` 中的浮动元素 `.a` 的实际高度为 30 + 20*2 = 70px,也就说当 `.b` 的 `margin-top` 大于 70px 时,超过的部分将会使得 `.b` 发生偏移。\n\n### CSS\n\n .b{\n clear:left;\n height:30px;\n margin-top:100px;\n }\n\n我们将 `DEMO2` 中的 `margin-top` 改成 100px,再看看具体情况 `DEMO3`:[clear margin 验证2](http://demo.doyoe.com/css/margin/bug/clear-margin-3.html),你可以手动的修改其 `margin-top` 值,看看临界值是否如前所述。\n\n## 解决方案\n\nIE6/7下由 `clear` 特性引发的 `margin-top` bug,并没有像 double margin 那样的万精油 `display:inline` 解决方案,所以需要寻求的是让IE6/7和其它浏览器绕过此问题来进行解决。\n\n例如:\n\n* 尽量避免为设置了 `clear` 为非 `none` 值的元素定义margin-top;\n* 如果必须,可以将拥有 `clear` 特性的元素作为容器,在其子元素上设置margin-top;\n* 视情况换成padding-top;\n\n## 要注意的问题\n\n`.a` 和 `.b` 需要在处在同一个块级上下文内,或者其包含块拥有 `padding-top/border-top`,否则临界值情况将失效,不过任何IE目前都不需要此前置条件。用IE和非IE查看 `DEMO4`:[clear margin 验证3](http://demo.doyoe.com/css/margin/bug/clear-margin-4.html)\n\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","source":"_posts/css/margin系列之bug巡演(二).md","raw":"title: margin系列之bug巡演(二)\ndate: 2013-12-17 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [margin, w3c, margin bug]\n---\n\n## IE6/7 clear引发的margin-top bug\n\n我知道,这是一个被谈及较少的bug,但我几乎可以肯定你在遇见过的同时并没有把它当成是一个bug。\n\n## w3c关于 clear 特性的描述\n\n设置了 `clear` 为非 `none` 值的元素,其顶部 `border` 边界在垂直方向不允许出现在之前的浮动元素底部 `margin` 之上。\n\n<!--more-->\n\n什么意思呢?用段代码来阐述:\n\n### HTML\n\n <div class=\"a\">float:left</div>\n <div class=\"b\">clear:left</div>\n\n### CSS\n\n .a{\n float:left;\n height:30px;\n margin:20px;\n }\n .b{\n clear:left;\n height:30px;\n margin-top:-30px;\n }\n\n如上代码,你认为 `.b` 是否会相对自身向上偏移 30px 呢?然后盖住 `.a` 底部 10px?如果你真这么猜想,那就错了。\n\n来看上述代码,我们会得到什么样的结果,如 `图一`:\n\n![clear margin](http://demo.doyoe.com/css/margin/images/clear-margin.png)(图一)\n\n恩,你觉得这可能会是落后浏览器才这样,比如IE6/7。很高兴的告诉你,其实高级浏览器才这样,IE6/7的表现会是之前你猜想的那样,如下 `图二`:\n\n![clear margin](http://demo.doyoe.com/css/margin/images/clear-margin-on-ie67.png)(图二)\n\n不论你相信与否,看个例子你就明白了 `DEMO1`:[clear margin 猜想](http://demo.doyoe.com/css/margin/bug/clear-margin.html),你会发现就算将 `margin-top` 去掉,`.b` 的位置也丝毫不会改变。\n\n## 为什么会这样?\n\n我们已经说过设置了 `clear` 为非 `none` 值的元素其顶部 `border` 边界不允许出现在之前浮动元素的底部margin边界之上。也就是说必须在垂直方向上递次堆叠却不能重合。\n\n所以说高级浏览器是遵循w3c规范的,而IE6/7的实现明显有悖该规则。\n\n虽然拥有 `clear` 特性的元素其 `border` 顶部边界不允许超越之前浮动元素的底部margin边界之上,但是其margin可以和之前浮动元素的任何区域重合。我们稍微改下之前代码:\n\n### HTML\n\n <div class=\"a\">float:left</div>\n <div class=\"b\">clear:left</div>\n\n### CSS\n\n .a{\n float:left;\n height:30px;\n margin:20px;\n }\n .b{\n clear:left;\n height:30px;\n margin-top:50px;\n }\n\n我们将 `.b` 的 `margin-top` 修改为一个正值,能得到如下 `图三`:\n\n![clear margin](http://demo.doyoe.com/css/margin/images/clear-margin-2.png)(图三)\n\n图中的黄色区域是 `.b` 的 `margin-top`,你会发现,它可以和 `.a` 的任何区域重合。同时,你也可以发现 `图三` 和 `图一` 居然是一样的效果,`.b` 的实际位置都没变化过。来看例子 `DEMO2`:[clear margin 验证](http://demo.doyoe.com/css/margin/bug/clear-margin-2.html)\n\n这是否说明拥有 `clear` 特性的元素对其之前的浮动元素没有任何影响?因为不论是正值还是负值,其位置都不会发生变化。\n\n如果你这样想,那你就又错了。\n\n## 拥有clear特性的元素其margin紧邻之前的浮动元素依然有效\n\n是的,在某个临界值,这一切会发生改变,并非全然无效。\n\n这个临界值是什么?\n\n临界值是包含块内浮动元素的实际高度,即浮动元素的 margin + border + padding + height,拿我们的 `DEMO2` 来详述:\n\n`DEMO2` 中的浮动元素 `.a` 的实际高度为 30 + 20*2 = 70px,也就说当 `.b` 的 `margin-top` 大于 70px 时,超过的部分将会使得 `.b` 发生偏移。\n\n### CSS\n\n .b{\n clear:left;\n height:30px;\n margin-top:100px;\n }\n\n我们将 `DEMO2` 中的 `margin-top` 改成 100px,再看看具体情况 `DEMO3`:[clear margin 验证2](http://demo.doyoe.com/css/margin/bug/clear-margin-3.html),你可以手动的修改其 `margin-top` 值,看看临界值是否如前所述。\n\n## 解决方案\n\nIE6/7下由 `clear` 特性引发的 `margin-top` bug,并没有像 double margin 那样的万精油 `display:inline` 解决方案,所以需要寻求的是让IE6/7和其它浏览器绕过此问题来进行解决。\n\n例如:\n\n* 尽量避免为设置了 `clear` 为非 `none` 值的元素定义margin-top;\n* 如果必须,可以将拥有 `clear` 特性的元素作为容器,在其子元素上设置margin-top;\n* 视情况换成padding-top;\n\n## 要注意的问题\n\n`.a` 和 `.b` 需要在处在同一个块级上下文内,或者其包含块拥有 `padding-top/border-top`,否则临界值情况将失效,不过任何IE目前都不需要此前置条件。用IE和非IE查看 `DEMO4`:[clear margin 验证3](http://demo.doyoe.com/css/margin/bug/clear-margin-4.html)\n\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","slug":"css/margin系列之bug巡演(二)","published":1,"updated":"2016-03-29T02:40:06.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvagz002u2ypkwojbowh6"},{"title":"margin系列之bug巡演(三)","date":"2013-12-20T03:15:00.000Z","author":"杜瑶","_content":"\n## IE8按钮margin auto居中失效Bug\n\n你会猛然觉得,这是正解啊,因为 `button` 或者 `input type button类型` 的元素是 `inline-level` 的。\n\n不对啊,`button` 应该是 `inline` 的吧?哦,可能是 `inline-block` ?\n\n在这之前,我们似乎要先明确一些基础知识。\n\n## 什么是 inline-level 元素?\n\n<!--more-->\n\n要知道 `inline-level` 元素并不等于 `inline` 元素,也就是说 `行内级元素` 与 `行内元素` 是两个不同的概念。\n\n### `inline-level` 元素包含 `display` 值为:\n\n* inline\n* inline-block\n* inline-table\n* inline-flex\n* other inline-*\n\n以上情况时,元素可被称之为 `inline-level` 元素,但不都是 `inline` 元素。\n\n## 什么是 block-level 元素?\n\n`block-level` 指的是 `display` 值为 `block` 的元素吗?我知道不少人一直有这样的认知,不过这不完全准确。\n\n### `block-level` 元素包含 `display` 值为:\n\n* block\n* list-item\n* table\n* table-*\n* flex\n* 如果position既不是static也不是relative、float不是none或者元素是根元素,当display:inline-table时,display的计算值为table;当display值为 inline | inline-block | run-in | table-* 时,display的计算值为block\n\n有如上情况时的元素均被称之为 `block-level` 元素。同时 `block-level` 和 `block` 也不是同一个概念,所以如果你认为 `display` 值为 `list-item` 的 li 不是 块级元素,那就错了。\n\n看到这里,你对 `块级元素`,`块元素`,`行内级元素`,`行内元素` 这个4个概念,应该已经有了比较清晰的了解?\n\n## margin keyword auto只能应用在常规流中的 block-level 元素上\n\n* 当一个块级元素定义了 `position` 值为非 `static` 和 `relative` 之外的值时,margin-right/left auto 的计算值为0;\n* 当一个块级元素定义了 `float` 值为非 `none` 之外的值时,margin-right/left auto 的计算值为0;\n* 非块级元素的margin-right/left auto 的计算值为0;\n\n计算值为0,即说明其应用使用值的意图失败。所以在有如上情形的场景中,都无法使用 `auto` 来实现水平居中。同时也说明了,只有 `normal flow` 的 `block-level` 才能应用 margin keyword auto。\n\n## margin可以应用于所有元素吗?\n\n这显然不行。准确的说:margin可以应用在除某些table-*元素和某些行内元素之外的所有元素上。\n\n### 和margin亲近的table-*系元素\n\n* table\n* inline-table\n* table-caption\n\n除了 `display` 值为以上3种之外的 `table系` 元素,都不能应用 `margin` ,比如:th, td。\n\n### 和margin亲近的 inline-level 元素\n\n我之前面试的时候常会问候选人,行内元素不能设置宽高对吗?大部分人会告诉我说是;然后我又会问,那为什么 `img` 元素可以设置宽高呢?有人会告诉我,因为 `img` 是个特殊的元素?接着我又会问题,`img` 是如何特殊的?然后,然后就没然后了,因为没声音了。\n\n恩,`img` 确实是个特殊的元素。它特殊在哪里?它的特殊就在于它是一个行内置换元素。\n\n所有的置换元素都可以设置 `margin` 属性,并且可以设置宽高,这就是为什么 `img` 是行内元素却可以设置 `width` 和 `height`。\n\n### 什么是置换元素(Replaced elements)?\n\n一个元素拥有内在的二维属性,其宽高属性受外部资源影响,默认拥有CSS格式,这样的元素被称为置换元素。\n\n意思就是说置换元素的宽高不完全由CSS决定,还受其自身内容和外部资源所影响。\n\n举个例子来说,仍然说 `img` 元素吧,你会发现,如果你 `src` 进来不同尺寸的资源,那么在 viewport 上显示的图片宽高也是不同的,也就是说 `img` 元素的宽高会受外部资源影响。\n\n再说说 `input` 元素,随便在页面上扔一个input,你都能发现它拥有一个默认的宽高,这就是它所具有的内在二维宽高属性,并且该类元素会受UA影响,不同UA下所呈现外观会有不同。\n\n### 常见的置换元素有哪些?\n\nimg, object, button, input, textarea, select等\n\n### 行内非置换元素真的不能应用margin吗?\n\n什么是非置换元素?除了置换元素之外的元素,我想将这样的元素称之为非置换元素是没有大碍的。\n\n那么行内非置换元素真的无法设置 `margin` 吗?我想在工作中你一定碰到过很多这样的场景,给一个 `a` 或者 `span` 定义间隙。这时我们写:\n\n### CSS\n\n span{margin:5px 10px;}\n\n结果发现 `span` 的水平方向上的 `margin` 定义生效了,但垂直方向上的 `margin` 定义却没被应用。\n\n是的,这就是行内非置换元素使用 `margin` 时的表征,所以对各种特性的理解,在让自己的代码更有效上是大有裨益的。\n\n## 回归正题\n\n我们本来是想说IE8按钮margin auto居中失效Bug的,扯了不少题外话。\n\n我们知道 margin keyword auto 不能应用在处于常规流中的 block-level 之外的元素上,所以我有这样的一段代码:\n\n### CSS\n\n button{display:block;margin:auto;}\n\n### HTML\n <div id=\"demo\">\n <button>按钮</button>\n </div>\n\n恩,我们将 `button` 显式的转换为了 `block`,同时我们知道 `button` 作为置换元素,本身具备内在宽高,也就是说这时,我只需要加上 `margin:auto` ,该按钮就应该在其包含块里水平居中。\n\n是的,所有浏览器都和预期是一样,实现了水平居中,但是却出现了奇葩的IE8,完全无效,甚至不如原始社会的IE6。来看看示例 `DEMO1`:[IE8按钮margin auto居中失效Bug](http://demo.doyoe.com/css/margin/bug/button-auto-margin-bug.html)\n\n通过以上例子,你有没有突然感觉到,如果要让一个置换元素在包含块中水平居中,出乎预料的简单,只需要 `display:block;margin:auto;` 即可。\n\n## 注意事项\n\n令人意外的是,只有 `button` 和 input type 为 button 相关元素的时候,在IE8中才会水平居中失效;如: `input type text` 或 `img` 时,margin keyword auto 运作正常。\n\n## 解决方案\n\n* 给其显示的定义宽度\n* 不改变其display值,包含块text-align:center\n* 其它水平居中方案,如:absolute + 负margin\n\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","source":"_posts/css/margin系列之bug巡演(三).md","raw":"title: margin系列之bug巡演(三)\ndate: 2013-12-20 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [margin, w3c, margin bug]\n---\n\n## IE8按钮margin auto居中失效Bug\n\n你会猛然觉得,这是正解啊,因为 `button` 或者 `input type button类型` 的元素是 `inline-level` 的。\n\n不对啊,`button` 应该是 `inline` 的吧?哦,可能是 `inline-block` ?\n\n在这之前,我们似乎要先明确一些基础知识。\n\n## 什么是 inline-level 元素?\n\n<!--more-->\n\n要知道 `inline-level` 元素并不等于 `inline` 元素,也就是说 `行内级元素` 与 `行内元素` 是两个不同的概念。\n\n### `inline-level` 元素包含 `display` 值为:\n\n* inline\n* inline-block\n* inline-table\n* inline-flex\n* other inline-*\n\n以上情况时,元素可被称之为 `inline-level` 元素,但不都是 `inline` 元素。\n\n## 什么是 block-level 元素?\n\n`block-level` 指的是 `display` 值为 `block` 的元素吗?我知道不少人一直有这样的认知,不过这不完全准确。\n\n### `block-level` 元素包含 `display` 值为:\n\n* block\n* list-item\n* table\n* table-*\n* flex\n* 如果position既不是static也不是relative、float不是none或者元素是根元素,当display:inline-table时,display的计算值为table;当display值为 inline | inline-block | run-in | table-* 时,display的计算值为block\n\n有如上情况时的元素均被称之为 `block-level` 元素。同时 `block-level` 和 `block` 也不是同一个概念,所以如果你认为 `display` 值为 `list-item` 的 li 不是 块级元素,那就错了。\n\n看到这里,你对 `块级元素`,`块元素`,`行内级元素`,`行内元素` 这个4个概念,应该已经有了比较清晰的了解?\n\n## margin keyword auto只能应用在常规流中的 block-level 元素上\n\n* 当一个块级元素定义了 `position` 值为非 `static` 和 `relative` 之外的值时,margin-right/left auto 的计算值为0;\n* 当一个块级元素定义了 `float` 值为非 `none` 之外的值时,margin-right/left auto 的计算值为0;\n* 非块级元素的margin-right/left auto 的计算值为0;\n\n计算值为0,即说明其应用使用值的意图失败。所以在有如上情形的场景中,都无法使用 `auto` 来实现水平居中。同时也说明了,只有 `normal flow` 的 `block-level` 才能应用 margin keyword auto。\n\n## margin可以应用于所有元素吗?\n\n这显然不行。准确的说:margin可以应用在除某些table-*元素和某些行内元素之外的所有元素上。\n\n### 和margin亲近的table-*系元素\n\n* table\n* inline-table\n* table-caption\n\n除了 `display` 值为以上3种之外的 `table系` 元素,都不能应用 `margin` ,比如:th, td。\n\n### 和margin亲近的 inline-level 元素\n\n我之前面试的时候常会问候选人,行内元素不能设置宽高对吗?大部分人会告诉我说是;然后我又会问,那为什么 `img` 元素可以设置宽高呢?有人会告诉我,因为 `img` 是个特殊的元素?接着我又会问题,`img` 是如何特殊的?然后,然后就没然后了,因为没声音了。\n\n恩,`img` 确实是个特殊的元素。它特殊在哪里?它的特殊就在于它是一个行内置换元素。\n\n所有的置换元素都可以设置 `margin` 属性,并且可以设置宽高,这就是为什么 `img` 是行内元素却可以设置 `width` 和 `height`。\n\n### 什么是置换元素(Replaced elements)?\n\n一个元素拥有内在的二维属性,其宽高属性受外部资源影响,默认拥有CSS格式,这样的元素被称为置换元素。\n\n意思就是说置换元素的宽高不完全由CSS决定,还受其自身内容和外部资源所影响。\n\n举个例子来说,仍然说 `img` 元素吧,你会发现,如果你 `src` 进来不同尺寸的资源,那么在 viewport 上显示的图片宽高也是不同的,也就是说 `img` 元素的宽高会受外部资源影响。\n\n再说说 `input` 元素,随便在页面上扔一个input,你都能发现它拥有一个默认的宽高,这就是它所具有的内在二维宽高属性,并且该类元素会受UA影响,不同UA下所呈现外观会有不同。\n\n### 常见的置换元素有哪些?\n\nimg, object, button, input, textarea, select等\n\n### 行内非置换元素真的不能应用margin吗?\n\n什么是非置换元素?除了置换元素之外的元素,我想将这样的元素称之为非置换元素是没有大碍的。\n\n那么行内非置换元素真的无法设置 `margin` 吗?我想在工作中你一定碰到过很多这样的场景,给一个 `a` 或者 `span` 定义间隙。这时我们写:\n\n### CSS\n\n span{margin:5px 10px;}\n\n结果发现 `span` 的水平方向上的 `margin` 定义生效了,但垂直方向上的 `margin` 定义却没被应用。\n\n是的,这就是行内非置换元素使用 `margin` 时的表征,所以对各种特性的理解,在让自己的代码更有效上是大有裨益的。\n\n## 回归正题\n\n我们本来是想说IE8按钮margin auto居中失效Bug的,扯了不少题外话。\n\n我们知道 margin keyword auto 不能应用在处于常规流中的 block-level 之外的元素上,所以我有这样的一段代码:\n\n### CSS\n\n button{display:block;margin:auto;}\n\n### HTML\n <div id=\"demo\">\n <button>按钮</button>\n </div>\n\n恩,我们将 `button` 显式的转换为了 `block`,同时我们知道 `button` 作为置换元素,本身具备内在宽高,也就是说这时,我只需要加上 `margin:auto` ,该按钮就应该在其包含块里水平居中。\n\n是的,所有浏览器都和预期是一样,实现了水平居中,但是却出现了奇葩的IE8,完全无效,甚至不如原始社会的IE6。来看看示例 `DEMO1`:[IE8按钮margin auto居中失效Bug](http://demo.doyoe.com/css/margin/bug/button-auto-margin-bug.html)\n\n通过以上例子,你有没有突然感觉到,如果要让一个置换元素在包含块中水平居中,出乎预料的简单,只需要 `display:block;margin:auto;` 即可。\n\n## 注意事项\n\n令人意外的是,只有 `button` 和 input type 为 button 相关元素的时候,在IE8中才会水平居中失效;如: `input type text` 或 `img` 时,margin keyword auto 运作正常。\n\n## 解决方案\n\n* 给其显示的定义宽度\n* 不改变其display值,包含块text-align:center\n* 其它水平居中方案,如:absolute + 负margin\n\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","slug":"css/margin系列之bug巡演(三)","published":1,"updated":"2016-03-29T02:40:09.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvah200302ypkeso0e7tu"},{"title":"margin系列之bug巡演","date":"2013-12-10T03:15:00.000Z","author":"杜瑶","_content":"\n## 我所知道的浏览器margin bug\n\n* IE6浮动双倍margin bug;\n* IE6浮动相邻元素3px bug;\n* IE6/7 clear引发的margin-top bug;\n* 待补充的有一堆\n\n## 为bug生为bug死为bug欲仙欲死的日子\n\n各浏览器的实现差异或者由此而引入的错误,一直都是前端开发人员的梦魇。相信大多数的前端都为此而精疲力尽过,浏览器bug你所知有几?\n\n## IE6浮动双倍margin bug\n\n这当是IE6最为经典的bug之一。高大上的前端,你肯定从未与其失之交臂过。\n\n## 触发方式\n\n* 元素被设置浮动\n* 元素在与浮动一致的方向上设置margin值\n\n<!--more-->\n\n来看看详细的代码吧:\n\n### HTML\n\n <div id=\"demo\">\n <p>IE6下浮动方向上的margin值将会双倍于其指定值</p>\n </div>\n\n### CSS\n\n #demo p{\n float:left;\n margin-left:10px;\n }\n\n### 效果对比\n\n![非IE6下浮动无双边距](http://demo.doyoe.com/css/margin/images/double-margin-non-ie6.png) (图一)\n\n图一 是非IE6下的效果\n\n![IE6下浮动双边距](http://demo.doyoe.com/css/margin/images/double-margin-on-ie6.png) (图二)\n\n图二 是IE6下的效果\n\n从图一和图二的对比,我们肉眼就可以发现区别。是的,IE6下左边的外边距变成了 `margin-left` 指定值的2倍,而其它浏览器下正常,这就是经典的IE6浮动元素双倍边距bug。来看看具体的例子:`DEMO1` [IE6浮动元素双倍margin bug重现](http://demo.doyoe.com/css/margin/bug/double-margin.html)\n\n很开心告诉你,问题要比这还更复杂一些,接着往下看。\n\n## 同个浮动方向的元素只有第一个元素会double margin\n\n`double margin` 并不会发生在所有的浮动元素上,同个包含块内,在相同的浮动方向上,它只发生在第一个浮动元素上。\n\n用代码说话:\n\n### HTML\n\n <div id=\"demo\">\n <p>第一个float:left</p>\n <p>第二个float:left</p>\n <p>第三个float:left</p>\n </div>\n\nCSS Code不变,加多2个浮动元素,再来看具体情况,有图有真相:\n\n![同个浮动方向的元素只有第一个元素会double margin](http://demo.doyoe.com/css/margin/images/double-margin-only-first-child-on-ie6.png) (图三)\n\n看到图三结果一目了然,三个 `float:left` 的元素只有第一个元素才 `double margin` 了。用个例子来终结它:`DEMO2` [同个浮动方向的元素只有第一个元素会double margin](http://demo.doyoe.com/css/margin/bug/double-margin-2.html)\n\n## double margin只发生在float:left时?\n\n你觉得呢?结果当然不会是这样。在之前,我们只说过在同个浮动方向的第一个浮动元素会double margin,并没有说只有 `float:left` 才触发。\n\n我们将 `DEMO1` 的CSS简单改改,HTML不变\n\n### CSS\n\n #demo p{\n float:right;\n margin-right:10px;\n }\n\n结果会是怎样呢?看 `图四`:\n\n![IE6 double margin也会发生在float:right时](http://demo.doyoe.com/css/margin/images/double-margin-on-ie6-3.png) (图四)\n\n在图四中,我们看到右侧的外边距明显比指定值 `margin-right:10px` 要大,恩,确实,它是20px,也double了。瞧瞧:`DEMO3` [IE6 double margin也会发生在float:right时](http://demo.doyoe.com/css/margin/bug/double-margin-3.html)\n\n## 既有左浮动又有右浮动的情况将会是怎样呢?\n\n我们先来将代码呈上:\n\n### HTML\n\n <div id=\"demo\">\n <p class=\"a\">1 float:left</p>\n <p class=\"b\">2 float:left</p>\n <p class=\"c\">3 float:right</p>\n <p class=\"d\">4 float:right</p>\n </div>\n\n### CSS\n\n #demo .a,#demo .b{\n float:left;\n margin-left:10px;\n }\n #demo .c,#demo .d{\n float:right;\n margin-right:10px;\n }\n\n是的,你可能想到了,第一个左浮动元素和第一个右浮动元素都将会出现 double margin。来看 `图五`:\n\n![既有左浮动又有右浮动的情况](http://demo.doyoe.com/css/margin/images/double-margin-on-ie6-4.png) (图五)\n\n左右都 double margin 了,这看似挺复杂,其实为什么会这样,前面都讲得比较明白了,所以应该能理解?本例也奉上:`DEMO4` [复杂的double margin](http://demo.doyoe.com/css/margin/bug/double-margin-4.html)\n\n## double margin 不仅仅出现在margin-left/right\n\n和大多数其它 `margin` 特性一样,double margin 也受书写模式 `writing-mode` 影响。我们在开篇所说的触发条件之一 `元素在与浮动一致的方向设置margin值` ,其实并不完全精确。当 `writing-mode` 为纵向时,会发生 double margin 的方向也相应变成了纵向。\n\n当书写模式 `writing-mode` 纵向时,设置 `float:right` 时,会发生什么?来看代码:\n\n### HTML\n\n <div id=\"demo\">\n <p>书写模式改变双倍margin bug方向</p>\n </div>\n\n### CSS\n\n #demo{\n -webkit-writing-mode:vertical-rl;\n writing-mode:tb-rl;\n }\n #demo p{\n float:right;\n margin:10px 0;\n }\n\nCSS Code中,我们同时设置了 `margin-top/bottom` 的值都为 10px。你预期会 double 的方向是 top or bottom?不太确定?看到 `图六` 你就知道了:\n\n![书写模式改变IE6浮动双倍margin bug方向](http://demo.doyoe.com/css/margin/images/double-margin-writing-mode-on-ie6.png) (图六)\n\n图六清晰的验证了 `writing-mode` 会影响 double margin 的方向;并且当设置了 `float:right` 时,只有 `margin-bottom` 会 double。看看示例吧:`DEMO5` [书写模式改变IE6浮动双倍margin bug方向](http://demo.doyoe.com/css/margin/bug/double-margin-tbrl.html)\n\n## `float:left` 时, double margin 的将会是 top or bottom?\n\n大家再猜猜,在书写模式为纵向时,设置了 `float:left`,结果又将会如何?\n\n我们只简单的将 `DEMO5` 中的CSS改成 `float:left` 其余不变,于是得到 `图七` 如下:\n\n![书写模式改变IE6浮动双倍margin bug方向](http://demo.doyoe.com/css/margin/images/double-margin-writing-mode-on-ie6-2.png) (图七)\n\n你会惊讶的发现,`margin-top/bottom` 两个方向都出现了 double,这真是一件好神奇的事,事实胜于雄辩:`DEMO6` [书写模式纵向时margin-top/bottom都将double](http://demo.doyoe.com/css/margin/bug/double-margin-tbrl-2.html)\n\n写到这,关于IE6浮动双倍margin bug就说的差不多了,包括触发方式,各种情景下的变化,还有解决方案。哦,解决方案貌似还没写...\n\n## fix IE6浮动双倍margin bug\n\n我们以 `DEMO1` 作为需要fix的case\n\n### 给IE6在会 double margin 的方向上设置小一倍的margin值,如下:\n\n### CSS\n\n #demo p{\n float:left;\n margin-left:10px;\n _margin-left:5px;\n }\n\n恩,IE6的hack,就不再赘述了。不过这种处理方式有一个明显的缺陷,那就是不够灵活,无法通用。因为当标准 margin 值改变时,这个值就得变化。所以不推荐使用这种方式。\n\n### display:inline\n\n### CSS\n\n #demo p{\n \t_display:inline;\n float:left;\n margin-left:10px;\n }\n\n恩,仍然是only ie6的hack,不过这个方案更Cool,它不需要care margin值到底是什么,足够灵活。看具体的例子吧:`DEMO7` [修复IE6浮动双倍margin bug](http://demo.doyoe.com/css/margin/bug/double-margin-fix.html)。至于为什么会有这种解法,我想只能问问微软的童鞋了。\n\n完全没想到,单一个双边距bug就写了这么长的篇幅,本打算一篇文章涵盖一堆bug,看来得分篇了。\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","source":"_posts/css/margin系列之bug巡演.md","raw":"title: margin系列之bug巡演\ndate: 2013-12-10 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [margin, w3c, margin bug]\n---\n\n## 我所知道的浏览器margin bug\n\n* IE6浮动双倍margin bug;\n* IE6浮动相邻元素3px bug;\n* IE6/7 clear引发的margin-top bug;\n* 待补充的有一堆\n\n## 为bug生为bug死为bug欲仙欲死的日子\n\n各浏览器的实现差异或者由此而引入的错误,一直都是前端开发人员的梦魇。相信大多数的前端都为此而精疲力尽过,浏览器bug你所知有几?\n\n## IE6浮动双倍margin bug\n\n这当是IE6最为经典的bug之一。高大上的前端,你肯定从未与其失之交臂过。\n\n## 触发方式\n\n* 元素被设置浮动\n* 元素在与浮动一致的方向上设置margin值\n\n<!--more-->\n\n来看看详细的代码吧:\n\n### HTML\n\n <div id=\"demo\">\n <p>IE6下浮动方向上的margin值将会双倍于其指定值</p>\n </div>\n\n### CSS\n\n #demo p{\n float:left;\n margin-left:10px;\n }\n\n### 效果对比\n\n![非IE6下浮动无双边距](http://demo.doyoe.com/css/margin/images/double-margin-non-ie6.png) (图一)\n\n图一 是非IE6下的效果\n\n![IE6下浮动双边距](http://demo.doyoe.com/css/margin/images/double-margin-on-ie6.png) (图二)\n\n图二 是IE6下的效果\n\n从图一和图二的对比,我们肉眼就可以发现区别。是的,IE6下左边的外边距变成了 `margin-left` 指定值的2倍,而其它浏览器下正常,这就是经典的IE6浮动元素双倍边距bug。来看看具体的例子:`DEMO1` [IE6浮动元素双倍margin bug重现](http://demo.doyoe.com/css/margin/bug/double-margin.html)\n\n很开心告诉你,问题要比这还更复杂一些,接着往下看。\n\n## 同个浮动方向的元素只有第一个元素会double margin\n\n`double margin` 并不会发生在所有的浮动元素上,同个包含块内,在相同的浮动方向上,它只发生在第一个浮动元素上。\n\n用代码说话:\n\n### HTML\n\n <div id=\"demo\">\n <p>第一个float:left</p>\n <p>第二个float:left</p>\n <p>第三个float:left</p>\n </div>\n\nCSS Code不变,加多2个浮动元素,再来看具体情况,有图有真相:\n\n![同个浮动方向的元素只有第一个元素会double margin](http://demo.doyoe.com/css/margin/images/double-margin-only-first-child-on-ie6.png) (图三)\n\n看到图三结果一目了然,三个 `float:left` 的元素只有第一个元素才 `double margin` 了。用个例子来终结它:`DEMO2` [同个浮动方向的元素只有第一个元素会double margin](http://demo.doyoe.com/css/margin/bug/double-margin-2.html)\n\n## double margin只发生在float:left时?\n\n你觉得呢?结果当然不会是这样。在之前,我们只说过在同个浮动方向的第一个浮动元素会double margin,并没有说只有 `float:left` 才触发。\n\n我们将 `DEMO1` 的CSS简单改改,HTML不变\n\n### CSS\n\n #demo p{\n float:right;\n margin-right:10px;\n }\n\n结果会是怎样呢?看 `图四`:\n\n![IE6 double margin也会发生在float:right时](http://demo.doyoe.com/css/margin/images/double-margin-on-ie6-3.png) (图四)\n\n在图四中,我们看到右侧的外边距明显比指定值 `margin-right:10px` 要大,恩,确实,它是20px,也double了。瞧瞧:`DEMO3` [IE6 double margin也会发生在float:right时](http://demo.doyoe.com/css/margin/bug/double-margin-3.html)\n\n## 既有左浮动又有右浮动的情况将会是怎样呢?\n\n我们先来将代码呈上:\n\n### HTML\n\n <div id=\"demo\">\n <p class=\"a\">1 float:left</p>\n <p class=\"b\">2 float:left</p>\n <p class=\"c\">3 float:right</p>\n <p class=\"d\">4 float:right</p>\n </div>\n\n### CSS\n\n #demo .a,#demo .b{\n float:left;\n margin-left:10px;\n }\n #demo .c,#demo .d{\n float:right;\n margin-right:10px;\n }\n\n是的,你可能想到了,第一个左浮动元素和第一个右浮动元素都将会出现 double margin。来看 `图五`:\n\n![既有左浮动又有右浮动的情况](http://demo.doyoe.com/css/margin/images/double-margin-on-ie6-4.png) (图五)\n\n左右都 double margin 了,这看似挺复杂,其实为什么会这样,前面都讲得比较明白了,所以应该能理解?本例也奉上:`DEMO4` [复杂的double margin](http://demo.doyoe.com/css/margin/bug/double-margin-4.html)\n\n## double margin 不仅仅出现在margin-left/right\n\n和大多数其它 `margin` 特性一样,double margin 也受书写模式 `writing-mode` 影响。我们在开篇所说的触发条件之一 `元素在与浮动一致的方向设置margin值` ,其实并不完全精确。当 `writing-mode` 为纵向时,会发生 double margin 的方向也相应变成了纵向。\n\n当书写模式 `writing-mode` 纵向时,设置 `float:right` 时,会发生什么?来看代码:\n\n### HTML\n\n <div id=\"demo\">\n <p>书写模式改变双倍margin bug方向</p>\n </div>\n\n### CSS\n\n #demo{\n -webkit-writing-mode:vertical-rl;\n writing-mode:tb-rl;\n }\n #demo p{\n float:right;\n margin:10px 0;\n }\n\nCSS Code中,我们同时设置了 `margin-top/bottom` 的值都为 10px。你预期会 double 的方向是 top or bottom?不太确定?看到 `图六` 你就知道了:\n\n![书写模式改变IE6浮动双倍margin bug方向](http://demo.doyoe.com/css/margin/images/double-margin-writing-mode-on-ie6.png) (图六)\n\n图六清晰的验证了 `writing-mode` 会影响 double margin 的方向;并且当设置了 `float:right` 时,只有 `margin-bottom` 会 double。看看示例吧:`DEMO5` [书写模式改变IE6浮动双倍margin bug方向](http://demo.doyoe.com/css/margin/bug/double-margin-tbrl.html)\n\n## `float:left` 时, double margin 的将会是 top or bottom?\n\n大家再猜猜,在书写模式为纵向时,设置了 `float:left`,结果又将会如何?\n\n我们只简单的将 `DEMO5` 中的CSS改成 `float:left` 其余不变,于是得到 `图七` 如下:\n\n![书写模式改变IE6浮动双倍margin bug方向](http://demo.doyoe.com/css/margin/images/double-margin-writing-mode-on-ie6-2.png) (图七)\n\n你会惊讶的发现,`margin-top/bottom` 两个方向都出现了 double,这真是一件好神奇的事,事实胜于雄辩:`DEMO6` [书写模式纵向时margin-top/bottom都将double](http://demo.doyoe.com/css/margin/bug/double-margin-tbrl-2.html)\n\n写到这,关于IE6浮动双倍margin bug就说的差不多了,包括触发方式,各种情景下的变化,还有解决方案。哦,解决方案貌似还没写...\n\n## fix IE6浮动双倍margin bug\n\n我们以 `DEMO1` 作为需要fix的case\n\n### 给IE6在会 double margin 的方向上设置小一倍的margin值,如下:\n\n### CSS\n\n #demo p{\n float:left;\n margin-left:10px;\n _margin-left:5px;\n }\n\n恩,IE6的hack,就不再赘述了。不过这种处理方式有一个明显的缺陷,那就是不够灵活,无法通用。因为当标准 margin 值改变时,这个值就得变化。所以不推荐使用这种方式。\n\n### display:inline\n\n### CSS\n\n #demo p{\n \t_display:inline;\n float:left;\n margin-left:10px;\n }\n\n恩,仍然是only ie6的hack,不过这个方案更Cool,它不需要care margin值到底是什么,足够灵活。看具体的例子吧:`DEMO7` [修复IE6浮动双倍margin bug](http://demo.doyoe.com/css/margin/bug/double-margin-fix.html)。至于为什么会有这种解法,我想只能问问微软的童鞋了。\n\n完全没想到,单一个双边距bug就写了这么长的篇幅,本打算一篇文章涵盖一堆bug,看来得分篇了。\n\n## margin系列文章:\n\n* [margin系列之布局篇](/2013/12/31/css/margin系列之布局篇/)\n* [margin系列之bug巡演(三)](/2013/12/20/css/margin系列之bug巡演(三)/)\n* [margin系列之bug巡演(二)](/2013/12/17/css/margin系列之bug巡演(二)/)\n* [margin系列之内秀篇(二)](/2013/12/14/css/margin系列之内秀篇(二)/)\n* [margin系列之bug巡演](/2013/12/10/css/margin系列之bug巡演/)\n* [margin系列之内秀篇](/2013/12/06/css/margin系列之内秀篇/)\n* [margin系列之外边距折叠](/2013/12/04/css/margin系列之外边距折叠/)\n* [margin系列之与相对偏移的异同](/2013/12/02/css/margin系列之与相对偏移的异同/)\n* [margin系列之百分比](/2013/11/30/css/margin系列之百分比/)\n* [margin系列之keyword auto](/2013/11/29/css/margin系列之keyword%20auto/)","slug":"css/margin系列之bug巡演","published":1,"updated":"2016-03-29T02:40:02.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvah400352ypki5fkxxjp"},{"title":"background系列之无处不在的妙趣","date":"2016-04-11T03:15:00.000Z","author":"杜瑶","_content":"\n## 前言\n\n上次和大家聊过 [background系列之你不知道的background-position](/2016/03/28/css/background系列之你不知道的background-position/),向大家展示了里面的一些小细节和未被发掘出来的特征。应该说 `background` 是一个很有意思的东西,不仅实际使用的频度超高,而且处处充满着好玩的妙趣。\n\n## 老需求\n\n这里并不打算和大家聊所谓的最佳实践,更多的是希望可以通过一些示例激起大家更深层次的思考和探索欲。\n\n<!--more-->\n\n大家来看下面这个例子,应该算是`iOS`中的典型列表风格,如`图0`:\n\n![图0:iOS风格列表](http://demo.doyoe.com/css3/background/skin/divider.png)\n\n从`图0`我们能看到这个列表中每个子项都有一根底边线,假设子项高为`40px`,并且除了最后一根边线是全封闭的外,其余的边线都是非封闭型,距左侧有一定的空白间隙;需要注意的是,当某个子项被选中或激活时,其反馈区域是整行,未封闭区域的背景色也需要改变,如`图0`中的第4行效果所示。\n\n我们来细化一下需求:\n\n1. 每个子项都需要底边线;\n2. 除了最后一根边线,其余边线都是非封闭的;\n3. 子项被选中或激活时,响应区域为整行;\n\n假设这就是我们现在的需求,你会如何实现呢?\n\n## 老思路\n\n我知道,通常来说,大家首先会想到的应该是`border`属性,然后配合`margin`来做这件事。\n\n于是我们可能会这样来写HTML:\n\n### HTML:\n```html\n<ul class=\"demo\">\n <li>Lady gaga</li>\n <li>Mariah Carey</li>\n <li>Adele</li>\n <li>Avril Lavigne</li>\n <li>Sarah Brightman</li>\n <li>Celine Dion</li>\n</ul>\n```\n\n为了实现需求第1点,CSS这样写:\n\n### CSS:\n```css\n.demo li {\n border-bottom: 1px solid #ccc;\n line-height: 40px;\n}\n```\n\nCool,简直太简单了。然后我们又接着来实现第2点:\n\n### CSS:\n```css\n.demo li {\n margin-left: 15px;\n}\n.demo li:last-child {\n margin-left: 0;\n padding-left: 15px;\n}\n```\n\n第2点好像也没有想象中那么复杂,就是需要把代码写恶心点,重置最后一个子项的`margin-left`,并换用`padding-left`,但貌似也还可以接受,毕竟只有2行代码。\n\n一鼓作气,我们需要继续把第3点也给做了,为了更好的理解,这里把`选中或激活`的状态用`经过`替代,其实是类似的,于是继续写:\n\n### CSS:\n```css\n.demo li:hover {\n background-color: #f3f3f3;\n}\n```\n\n迫不及待要看看这样写是否能符合预期了,如下`图1`:\n\n![图1:方案1效果图](http://demo.doyoe.com/css3/background/skin/bad-divider.png)\n\n开心的是,需求中的第1,2两点都做到了;难受的是,第3点没达成。从`图1`我们就能看到,响应区域除了最后一项外,其它的项都不是整行的。可以直接来观看这个例子, `Demo1` [使用border和margin做iOS风格列表](http://demo.doyoe.com/css3/background/border-divider.htm)\n\n很明显,这个解决方案失败了。败在了`margin`区域无法承载`background`,因为`margin`永远是透明的,围绕在盒子之外。有兴趣的童鞋可以翻翻规范了解这些信息。\n\n## 再出发\n\n虽然说`方案1`有问题,但我们也知道了,如果是使用`margin`来做的间隙,那么将无法填充背景,而`padding`是可以的,那么这就可以作为下个方案的指导。\n\n有了这样的指导,我们是不是可以考虑将内容的间隙和边线的间隙分开处理?内容仍然使用`padding`,边线额外处理,互不影响,避免出现`方案1`的情况。\n\n不论怎样,我相信在大多数时候,你都不想为了达到某个效果,而增加层级。所以这里,不在之前`HTML`上做任何改变,那么要单独处理边线,我们就只能给它创造一个`伪元素`了。\n\n于是我们又开始一一实现,首先,内容要有间隙:\n\n### CSS:\n```css\n.demo li {\n padding-left: 15px;\n line-height: 40px;\n}\n```\n\n接下来,每个子项都要有底边线。说好的`伪元素`,我们不能抛弃:\n\n### CSS:\n```css\n.demo li::after {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n border-bottom: 1px solid #ccc;\n content: \"\\0020\";\n}\n```\n\n我们还需要让出了最后一根边线外的其它边线距左侧有间隙:\n\n### CSS:\n```css\n.demo li:not(:last-child)::after {\n left: 15px;\n}\n```\n\n就剩最后一点了,来给它们加上响应反馈效果:\n\n### CSS:\n```css\n.demo li:hover {\n background-color: #f3f3f3;\n}\n```\n\n嗯,差不多了。貌似还差点,我们的边线的是绝对定位的,所以还需要给它的包含块加上定位:\n\n### CSS:\n```css\n.demo li {\n position: relative;\n}\n```\n\n这下看起来是处理得差不多了,让我们来瞧瞧实际的效果,如`图2`:\n\n![图2:方案2效果图](http://demo.doyoe.com/css3/background/skin/pseudo-element-divider.png)\n\nGood job! `方案2`完全实现我们的预期,可以看具体的示例:`Demo2` [使用伪元素做iOS风格列表](http://demo.doyoe.com/css3/background/pseudo-element-divider.htm)\n\n## 精益求精\n\n`方案2`虽然已经完全实现了需求,但我总是有点不太喜欢它。因为我发现,当内容的边距修改后,边线的边距也需要手动修改,问题就在于它们被分别处理了;而且代码居然超过10行了。\n\n所以,如果我不想只要改变边距就得改2处地方,还是只能讲它们合起来处理,不再分开。这意味着`伪元素`不再是我们需要考虑的,包括`方案1`中的`margin`也要排除。\n\n怎么办?貌似有点棘手了。\n\n可能大家已经猜到我会把注意力放到`background`上了,毕竟好像这个系列讲的就是`background`,但不知道会不会猜到我准备怎么做。\n\n## 旧酒新衣\n\n用`background`做边线这样的方案,不少童鞋肯定遇上过,比如说:菜单之间的分隔竖线(当然,这个能用几十种方式来做),这个比较简单,或用背景图,或用伪元素承载背景色。\n\n然后在当前这个需求背景下,这些方式都不适用了。显然,我不会在真实的背景图片方向去考虑这个问题,毕竟我懒嘛,并不想切图。\n\n所以,我得打打渐变背景的主意了,大家知道我们其实是可以用渐变来画背景图像的。于是,我又开始写了,当然,`HTML`仍然不变:\n\n### CSS:\n```css\n.demo li {\n padding-left: 15px;\n line-height: 40px;\n background: linear-gradient(#ccc, #ccc) no-repeat;\n}\n```\n\n好了,内容的边距有了;渐变背景也有了(虽然是纯色的),但它不是线,不是线。得改改,我们是不是可以让渐变从透明渐变到边线的颜色呢?试试:\n\n### CSS:\n```css\n.demo li {\n padding-left: 15px;\n line-height: 40px;\n background: linear-gradient(transparent 39px, #ccc 39px, #ccc) no-repeat;\n}\n```\n\n我们让渐变背景从`transparent`渐变到`#ccc`,`transparent`区域占`39px`,剩下`1px`给`#ccc`。\n\n事实上,这是可行的,运行结果如我所想,但我还要处理一下边线距左侧的边距问题和响应反馈:\n\n### CSS:\n```css\n.demo li:not(:last-child) {\n background-position: 15px;\n}\n.demo li:hover {\n background-color: #f3f3f3;\n}\n```\n\n搞定了,赶紧看下效果,如`图3`:\n\n![图3:方案3效果图](http://demo.doyoe.com/css3/background/skin/gradient-background-divider.png)\n\n结果确实正如我想,可以看具体的示例:`Demo3` [使用渐变背景做iOS风格列表](http://demo.doyoe.com/css3/background/gradient-background-divider.htm)\n\n## 新的突破\n\n通过`方案3`的实现可以发现使用渐变背景来做边线是完全可用性,只是它也并没有解决我想要的只改`1处`边距就同时处理了内容边距和边线边距。\n\n所以就只能再改改了,再发掘发掘`background`的其他魅力。\n\n我知道,`background`体系下有一个特性是用来控制背景图的渲染起始位置的,它可以根据设置,让背景图从`边框`,`内补白`或`内容`区域开始渲染。\n\n是的,你想起了,它是`background-origin`。\n\n因为最后一根边线是封闭的,无需再做任何处理了。但如果我们需要完成其它边线的边距随内容的边距变化而变化,那么就需要让边线从元素的`内补白`以内的区域开始渲染,即`内容`区域,于是我们这么改:\n\n### CSS:\n```css\n.demo li:not(:last-child) {\n background-origin: content-box;\n}\n```\n\n是的,就是这么一句简单的改动,我想要的都得到了。之后边线的边距将由内容的边距来决定,当我们将内容的边距改成`20px`时,边线的边距也将自动变成`20px`(当然,原因是因为背景图从元素的`content-box`区域开始渲染)。\n\n看看我们新突破后的成果吧,如`图4`:\n\n![图4:方案4效果图](http://demo.doyoe.com/css3/background/skin/gradient-background-divider.png)\n\n这是属于我们共同的胜利,可以看具体的示例:`Demo4` [使用渐变背景和背景图起始位置做iOS风格列表](http://demo.doyoe.com/css3/background/gradient-background-divider2.htm)\n\n这只是`background`趣味性的一个小点,后续应该会继续写一些。\n\n## 写在最后\n\n解决方案不是永远靠谱的,任何差异化的场景都不一定能复用以往的经验,但不停的探索是可以的,并且它是建立在扎实的基础上的。enjoy it.\n\n\n## background系列文章:\n\n* [background系列之无处不在的妙趣](/2016/04/11/css/background系列之无处不在的妙趣/)\n* [background系列之你不知道的background-position](/2016/03/28/css/background系列之你不知道的background-position/)","source":"_posts/css/background系列之无处不在的妙趣.md","raw":"title: background系列之无处不在的妙趣\ndate: 2016-4-11 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [background, background-origin, gradient, w3c, CSS应用]\n---\n\n## 前言\n\n上次和大家聊过 [background系列之你不知道的background-position](/2016/03/28/css/background系列之你不知道的background-position/),向大家展示了里面的一些小细节和未被发掘出来的特征。应该说 `background` 是一个很有意思的东西,不仅实际使用的频度超高,而且处处充满着好玩的妙趣。\n\n## 老需求\n\n这里并不打算和大家聊所谓的最佳实践,更多的是希望可以通过一些示例激起大家更深层次的思考和探索欲。\n\n<!--more-->\n\n大家来看下面这个例子,应该算是`iOS`中的典型列表风格,如`图0`:\n\n![图0:iOS风格列表](http://demo.doyoe.com/css3/background/skin/divider.png)\n\n从`图0`我们能看到这个列表中每个子项都有一根底边线,假设子项高为`40px`,并且除了最后一根边线是全封闭的外,其余的边线都是非封闭型,距左侧有一定的空白间隙;需要注意的是,当某个子项被选中或激活时,其反馈区域是整行,未封闭区域的背景色也需要改变,如`图0`中的第4行效果所示。\n\n我们来细化一下需求:\n\n1. 每个子项都需要底边线;\n2. 除了最后一根边线,其余边线都是非封闭的;\n3. 子项被选中或激活时,响应区域为整行;\n\n假设这就是我们现在的需求,你会如何实现呢?\n\n## 老思路\n\n我知道,通常来说,大家首先会想到的应该是`border`属性,然后配合`margin`来做这件事。\n\n于是我们可能会这样来写HTML:\n\n### HTML:\n```html\n<ul class=\"demo\">\n <li>Lady gaga</li>\n <li>Mariah Carey</li>\n <li>Adele</li>\n <li>Avril Lavigne</li>\n <li>Sarah Brightman</li>\n <li>Celine Dion</li>\n</ul>\n```\n\n为了实现需求第1点,CSS这样写:\n\n### CSS:\n```css\n.demo li {\n border-bottom: 1px solid #ccc;\n line-height: 40px;\n}\n```\n\nCool,简直太简单了。然后我们又接着来实现第2点:\n\n### CSS:\n```css\n.demo li {\n margin-left: 15px;\n}\n.demo li:last-child {\n margin-left: 0;\n padding-left: 15px;\n}\n```\n\n第2点好像也没有想象中那么复杂,就是需要把代码写恶心点,重置最后一个子项的`margin-left`,并换用`padding-left`,但貌似也还可以接受,毕竟只有2行代码。\n\n一鼓作气,我们需要继续把第3点也给做了,为了更好的理解,这里把`选中或激活`的状态用`经过`替代,其实是类似的,于是继续写:\n\n### CSS:\n```css\n.demo li:hover {\n background-color: #f3f3f3;\n}\n```\n\n迫不及待要看看这样写是否能符合预期了,如下`图1`:\n\n![图1:方案1效果图](http://demo.doyoe.com/css3/background/skin/bad-divider.png)\n\n开心的是,需求中的第1,2两点都做到了;难受的是,第3点没达成。从`图1`我们就能看到,响应区域除了最后一项外,其它的项都不是整行的。可以直接来观看这个例子, `Demo1` [使用border和margin做iOS风格列表](http://demo.doyoe.com/css3/background/border-divider.htm)\n\n很明显,这个解决方案失败了。败在了`margin`区域无法承载`background`,因为`margin`永远是透明的,围绕在盒子之外。有兴趣的童鞋可以翻翻规范了解这些信息。\n\n## 再出发\n\n虽然说`方案1`有问题,但我们也知道了,如果是使用`margin`来做的间隙,那么将无法填充背景,而`padding`是可以的,那么这就可以作为下个方案的指导。\n\n有了这样的指导,我们是不是可以考虑将内容的间隙和边线的间隙分开处理?内容仍然使用`padding`,边线额外处理,互不影响,避免出现`方案1`的情况。\n\n不论怎样,我相信在大多数时候,你都不想为了达到某个效果,而增加层级。所以这里,不在之前`HTML`上做任何改变,那么要单独处理边线,我们就只能给它创造一个`伪元素`了。\n\n于是我们又开始一一实现,首先,内容要有间隙:\n\n### CSS:\n```css\n.demo li {\n padding-left: 15px;\n line-height: 40px;\n}\n```\n\n接下来,每个子项都要有底边线。说好的`伪元素`,我们不能抛弃:\n\n### CSS:\n```css\n.demo li::after {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n border-bottom: 1px solid #ccc;\n content: \"\\0020\";\n}\n```\n\n我们还需要让出了最后一根边线外的其它边线距左侧有间隙:\n\n### CSS:\n```css\n.demo li:not(:last-child)::after {\n left: 15px;\n}\n```\n\n就剩最后一点了,来给它们加上响应反馈效果:\n\n### CSS:\n```css\n.demo li:hover {\n background-color: #f3f3f3;\n}\n```\n\n嗯,差不多了。貌似还差点,我们的边线的是绝对定位的,所以还需要给它的包含块加上定位:\n\n### CSS:\n```css\n.demo li {\n position: relative;\n}\n```\n\n这下看起来是处理得差不多了,让我们来瞧瞧实际的效果,如`图2`:\n\n![图2:方案2效果图](http://demo.doyoe.com/css3/background/skin/pseudo-element-divider.png)\n\nGood job! `方案2`完全实现我们的预期,可以看具体的示例:`Demo2` [使用伪元素做iOS风格列表](http://demo.doyoe.com/css3/background/pseudo-element-divider.htm)\n\n## 精益求精\n\n`方案2`虽然已经完全实现了需求,但我总是有点不太喜欢它。因为我发现,当内容的边距修改后,边线的边距也需要手动修改,问题就在于它们被分别处理了;而且代码居然超过10行了。\n\n所以,如果我不想只要改变边距就得改2处地方,还是只能讲它们合起来处理,不再分开。这意味着`伪元素`不再是我们需要考虑的,包括`方案1`中的`margin`也要排除。\n\n怎么办?貌似有点棘手了。\n\n可能大家已经猜到我会把注意力放到`background`上了,毕竟好像这个系列讲的就是`background`,但不知道会不会猜到我准备怎么做。\n\n## 旧酒新衣\n\n用`background`做边线这样的方案,不少童鞋肯定遇上过,比如说:菜单之间的分隔竖线(当然,这个能用几十种方式来做),这个比较简单,或用背景图,或用伪元素承载背景色。\n\n然后在当前这个需求背景下,这些方式都不适用了。显然,我不会在真实的背景图片方向去考虑这个问题,毕竟我懒嘛,并不想切图。\n\n所以,我得打打渐变背景的主意了,大家知道我们其实是可以用渐变来画背景图像的。于是,我又开始写了,当然,`HTML`仍然不变:\n\n### CSS:\n```css\n.demo li {\n padding-left: 15px;\n line-height: 40px;\n background: linear-gradient(#ccc, #ccc) no-repeat;\n}\n```\n\n好了,内容的边距有了;渐变背景也有了(虽然是纯色的),但它不是线,不是线。得改改,我们是不是可以让渐变从透明渐变到边线的颜色呢?试试:\n\n### CSS:\n```css\n.demo li {\n padding-left: 15px;\n line-height: 40px;\n background: linear-gradient(transparent 39px, #ccc 39px, #ccc) no-repeat;\n}\n```\n\n我们让渐变背景从`transparent`渐变到`#ccc`,`transparent`区域占`39px`,剩下`1px`给`#ccc`。\n\n事实上,这是可行的,运行结果如我所想,但我还要处理一下边线距左侧的边距问题和响应反馈:\n\n### CSS:\n```css\n.demo li:not(:last-child) {\n background-position: 15px;\n}\n.demo li:hover {\n background-color: #f3f3f3;\n}\n```\n\n搞定了,赶紧看下效果,如`图3`:\n\n![图3:方案3效果图](http://demo.doyoe.com/css3/background/skin/gradient-background-divider.png)\n\n结果确实正如我想,可以看具体的示例:`Demo3` [使用渐变背景做iOS风格列表](http://demo.doyoe.com/css3/background/gradient-background-divider.htm)\n\n## 新的突破\n\n通过`方案3`的实现可以发现使用渐变背景来做边线是完全可用性,只是它也并没有解决我想要的只改`1处`边距就同时处理了内容边距和边线边距。\n\n所以就只能再改改了,再发掘发掘`background`的其他魅力。\n\n我知道,`background`体系下有一个特性是用来控制背景图的渲染起始位置的,它可以根据设置,让背景图从`边框`,`内补白`或`内容`区域开始渲染。\n\n是的,你想起了,它是`background-origin`。\n\n因为最后一根边线是封闭的,无需再做任何处理了。但如果我们需要完成其它边线的边距随内容的边距变化而变化,那么就需要让边线从元素的`内补白`以内的区域开始渲染,即`内容`区域,于是我们这么改:\n\n### CSS:\n```css\n.demo li:not(:last-child) {\n background-origin: content-box;\n}\n```\n\n是的,就是这么一句简单的改动,我想要的都得到了。之后边线的边距将由内容的边距来决定,当我们将内容的边距改成`20px`时,边线的边距也将自动变成`20px`(当然,原因是因为背景图从元素的`content-box`区域开始渲染)。\n\n看看我们新突破后的成果吧,如`图4`:\n\n![图4:方案4效果图](http://demo.doyoe.com/css3/background/skin/gradient-background-divider.png)\n\n这是属于我们共同的胜利,可以看具体的示例:`Demo4` [使用渐变背景和背景图起始位置做iOS风格列表](http://demo.doyoe.com/css3/background/gradient-background-divider2.htm)\n\n这只是`background`趣味性的一个小点,后续应该会继续写一些。\n\n## 写在最后\n\n解决方案不是永远靠谱的,任何差异化的场景都不一定能复用以往的经验,但不停的探索是可以的,并且它是建立在扎实的基础上的。enjoy it.\n\n\n## background系列文章:\n\n* [background系列之无处不在的妙趣](/2016/04/11/css/background系列之无处不在的妙趣/)\n* [background系列之你不知道的background-position](/2016/03/28/css/background系列之你不知道的background-position/)","slug":"css/background系列之无处不在的妙趣","published":1,"updated":"2016-04-19T03:43:07.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvah8003a2ypkhiuzsz5i"},{"title":"background系列之你不知道的background-position","date":"2016-03-28T03:15:00.000Z","author":"杜瑶","_content":"\n## 这是一个有趣的话题\n\n其实我并不确切的平时大家是怎么去应用或者玩转一个属性,一个值。我能肯定的是这些东西都有不少的可玩性。\n\n我今天要聊的 `background-position` 应该已经被大家玩得色彩斑斓了。尤其是 `CSS Sprites` 流行的这些年,`background-position` 基本上是被应用最多的属性之一。\n\n## 重拾旧趣\n\n我们知道 `background-position` 是用来指定背景图像的偏移值的,能让一张图从特定的位置开始展现。而 `CSS Sprites` 就是通过将多个小图拼接成一张大图,然后利用 `background-position` 来指定需要显示的区域,以此达到合并HTTP请求的预期。\n\n<!--more-->\n\n## 一个足够简单的应用\n\n为了回顾 `background-position` 的应用,接下来我将会用一个最简单的例子来代入,这里有一张由2个 `300*100px` 垂直拼接而成的图片作为背景图,如 `图0`:\n\n![图0:简单的文字图片](http://demo.doyoe.com/css3/background-position/skin/text-image.png)\n\n我现在需要 `图0` 在2个并排的div中分别显示不同的部分:\n\n### HTML:\n```html\n<div class=\"part1\"><!-- 显示图0上半部分 --></div>\n<div class=\"part2\"><!-- 显示图0下半部分 --></div>\n```\n\n于是我写了段简单的CSS,如下:\n\n### CSS:\n```css\ndiv {\n width: 300px;\n height: 100px;\n background: gray url(../test.png) no-repeat;\n}\n.part1 {\n background-position: 0 0;\n}\n.part2 {\n background-position: 0 -100px;\n}\n```\n\n很显然我可以得到预期,效果如 `图1`:\n\n![图1:简单的CSS Sprites应用](http://demo.doyoe.com/css3/background-position/skin/normal.png)\n\n这就是最典型的 `CSS Sprites` 使用场景。当然,你可以在线查看这个例子 `Demo1` [最简单的 background-position 应用](http://demo.doyoe.com/css3/background-position/normal.htm)。\n\n## 默认值\n\n由于 `background-position` 的默认值是 `0% 0%`,那么上述的CSS代码其实可以优化成:\n\n```css\n.part2 {\n background-position: 0 -100px;\n}\n```\n\n因为 `.part1` 指定的值是 `0 0`,和默认值相同,所以可以省略。你会发现,对一个属性了解得更多,就更能帮助你写出简洁的代码。\n\n## 百分比\n\n我并不能确定大家是否使用过 `background-position` 的百分比,这里就权当大家对此并不甚了解。\n\n### 试着使用百分比去实现上个例子\n\n我相信肯定有童鞋会这样写:\n\n```css\n.part2 {\n /* background-position: 0 -100px; */\n background-position: 0 -50%;\n}\n```\n\n按照一般的思维,上述两行代码应该是等价的,不是么?在开篇的时候我们就说了背景图 `图0` 的高度是 `200px`,那么 `-50%` 正好是 `-100px`。\n\n不用着急,我们会用实际的例子来验证这个结果,来看 `Demo2` [检验 background-position 的百分比值](http://demo.doyoe.com/css3/background-position/percentage.htm)。\n\n![图2:参照尺寸验证](http://demo.doyoe.com/css3/background-position/skin/percentage.png)\n\n结果让人有点忧伤,这和我们的设想有点出入,这是为什么呢?\n\n### 追本溯源\n\n我们都知道一个百分比值,必然会需要有一个参照尺寸。举个例子来讲,假设我定义一个元素的宽度是 `50%`,那么这个元素的具体宽度就是:`包含块宽度 * 50%`。\n\n所以,如果你需要使用百分比作为 `background-position` 的值,必须清楚它的参照尺寸是什么。\n\n`w3c` 是这样描述 `background-position` 比分比值的:\n\n> 原文:refer to size of background positioning area minus size of background image.\n>\n> 翻译:参照指定背景区域的尺寸减去背景图片的尺寸\n\n这是什么意思呢?白话一点说:`background-position` 的百分比值参照的是设置背景的区域减去背景图的尺寸。\n\n### 再出发\n\n按照这个思路,我们将:\n\n```css\n.part2 {\n background-position: 0 -50%;\n}\n```\n\n换算一下将会得到:\n\n```css\n.part2 {\n background-position: 0 50px;\n}\n```\n\n换算过程为:(设置背景的区域高度 - 背景图的高度) \\* -50%,即:(100 - 200) \\* -50% = 50px\n\n这就解释了 `Demo2` 为什么会得到 `图2` 的效果。但这显然并不是我们想要的,我们预期的效果是 `图1`。\n\n根据上述的公式,我们可以逆推预期效果的百分比值是多少:\n\n```\n-100 / (100 - 200) = 100%\n```\n\n所以如果你要使用百分比,那么定义应该是这样的:\n\n```css\n.part2 {\n background-position: 0 100%;\n}\n```\n\n其结果如 `Demo3` [正确使用 background-position 百分比](http://demo.doyoe.com/css3/background-position/percentage-value.htm)\n\n这会终于得到我们的预期效果了,请看 `图3`\n\n![图3:百分比的正确预期效果](http://demo.doyoe.com/css3/background-position/skin/normal.png)\n\n了解了百分比的这个特性后,会帮助我们大大简化某些定义,比如我在 [Yo](https://github.com/doyoe/Yo) 里面对 [yo-score](http://blog.doyoe.com/Yo/demo/element/yo-score.html) 的处理,非常巧妙,有兴趣的童鞋可以自己研究一下,这里不细讲。\n\n另外:需要注意的是百分比值会受 `background-size` 影响,因为 `background-size` 可以改变背景图像的大小。\n\n## 多值\n\n在 `CSS3` 中,对 `background-position` 属性进行了扩展,允许接受3到4个参数,用于指定背景图的起始方向和具体位置。\n\n> 原文:If three or four values are given, then each <percentage> or <length> represents an offset and must be preceded by a keyword, which specifies from which edge the offset is given.\n>\n> 翻译:如果指定了三个或四个值,那么每个 <percentage> 或 <length> 之前必须有一个关键字,用于指定该方向的偏移量。\n\n当指定3到4个参数时,不接受 `center` 关键字作为偏移量作为边界,只能使用 `top, right, bottom, left` 这4个关键字。\n\n### 多值的意义\n\n在此前,我们使用 `background-position` 只能让背景图从 `top, right, bottom, left, center` 这5个边界开始显示,但无法指定任意一个边界的偏移量。\n\n举个例子:我想让一个背景图从右下角偏移 `20px`\n\n你会发现如果没有多值扩展,你很难轻易做到这件事,除非你能确定容器的宽高永远都是显式定义好的,就算如此,其灵活性也一文不值。\n\n### 多值的应用\n\n如果利用多值特性,这将变得非常轻松,我们仍使用 `图0` 作为背景图,来做一个演示。\n\n```\n.demo {\n width: 400px;\n height: 400px;\n background: url(../test.png) no-repeat;\n background-position: right -300px bottom 20px;\n}\n```\n\n这会终于得到我们的预期效果了,请看 `图4`\n\n![图4:背景图多值应用](http://demo.doyoe.com/css3/background-position/skin/multi-value.png)\n\n效果可以查看 `Demo4` [background-position 边界偏移](http://demo.doyoe.com/css3/background-position/multi-value.htm)。实际上,有了多值之后,我们可以让背景图在任意方位上偏移,你可能会发现,这甚至可以让你的结构写得更简单,嵌套变浅。\n\n## 写在最后\n\n当你深入了解了每个属性的每个定义,你的CSS世界又会变得和以前不一样。enjoy it.\n\n\n## background系列文章:\n\n* [background系列之你不知道的background-position](/2016/03/28/css/background系列之你不知道的background-position/)","source":"_posts/css/background系列之你不知道的background-position.md","raw":"title: background系列之你不知道的background-position\ndate: 2016-3-28 11:15:00\ncategories: CSS\nauthor: 杜瑶\ntags: [background, background-position, w3c, CSS应用]\n---\n\n## 这是一个有趣的话题\n\n其实我并不确切的平时大家是怎么去应用或者玩转一个属性,一个值。我能肯定的是这些东西都有不少的可玩性。\n\n我今天要聊的 `background-position` 应该已经被大家玩得色彩斑斓了。尤其是 `CSS Sprites` 流行的这些年,`background-position` 基本上是被应用最多的属性之一。\n\n## 重拾旧趣\n\n我们知道 `background-position` 是用来指定背景图像的偏移值的,能让一张图从特定的位置开始展现。而 `CSS Sprites` 就是通过将多个小图拼接成一张大图,然后利用 `background-position` 来指定需要显示的区域,以此达到合并HTTP请求的预期。\n\n<!--more-->\n\n## 一个足够简单的应用\n\n为了回顾 `background-position` 的应用,接下来我将会用一个最简单的例子来代入,这里有一张由2个 `300*100px` 垂直拼接而成的图片作为背景图,如 `图0`:\n\n![图0:简单的文字图片](http://demo.doyoe.com/css3/background-position/skin/text-image.png)\n\n我现在需要 `图0` 在2个并排的div中分别显示不同的部分:\n\n### HTML:\n```html\n<div class=\"part1\"><!-- 显示图0上半部分 --></div>\n<div class=\"part2\"><!-- 显示图0下半部分 --></div>\n```\n\n于是我写了段简单的CSS,如下:\n\n### CSS:\n```css\ndiv {\n width: 300px;\n height: 100px;\n background: gray url(../test.png) no-repeat;\n}\n.part1 {\n background-position: 0 0;\n}\n.part2 {\n background-position: 0 -100px;\n}\n```\n\n很显然我可以得到预期,效果如 `图1`:\n\n![图1:简单的CSS Sprites应用](http://demo.doyoe.com/css3/background-position/skin/normal.png)\n\n这就是最典型的 `CSS Sprites` 使用场景。当然,你可以在线查看这个例子 `Demo1` [最简单的 background-position 应用](http://demo.doyoe.com/css3/background-position/normal.htm)。\n\n## 默认值\n\n由于 `background-position` 的默认值是 `0% 0%`,那么上述的CSS代码其实可以优化成:\n\n```css\n.part2 {\n background-position: 0 -100px;\n}\n```\n\n因为 `.part1` 指定的值是 `0 0`,和默认值相同,所以可以省略。你会发现,对一个属性了解得更多,就更能帮助你写出简洁的代码。\n\n## 百分比\n\n我并不能确定大家是否使用过 `background-position` 的百分比,这里就权当大家对此并不甚了解。\n\n### 试着使用百分比去实现上个例子\n\n我相信肯定有童鞋会这样写:\n\n```css\n.part2 {\n /* background-position: 0 -100px; */\n background-position: 0 -50%;\n}\n```\n\n按照一般的思维,上述两行代码应该是等价的,不是么?在开篇的时候我们就说了背景图 `图0` 的高度是 `200px`,那么 `-50%` 正好是 `-100px`。\n\n不用着急,我们会用实际的例子来验证这个结果,来看 `Demo2` [检验 background-position 的百分比值](http://demo.doyoe.com/css3/background-position/percentage.htm)。\n\n![图2:参照尺寸验证](http://demo.doyoe.com/css3/background-position/skin/percentage.png)\n\n结果让人有点忧伤,这和我们的设想有点出入,这是为什么呢?\n\n### 追本溯源\n\n我们都知道一个百分比值,必然会需要有一个参照尺寸。举个例子来讲,假设我定义一个元素的宽度是 `50%`,那么这个元素的具体宽度就是:`包含块宽度 * 50%`。\n\n所以,如果你需要使用百分比作为 `background-position` 的值,必须清楚它的参照尺寸是什么。\n\n`w3c` 是这样描述 `background-position` 比分比值的:\n\n> 原文:refer to size of background positioning area minus size of background image.\n>\n> 翻译:参照指定背景区域的尺寸减去背景图片的尺寸\n\n这是什么意思呢?白话一点说:`background-position` 的百分比值参照的是设置背景的区域减去背景图的尺寸。\n\n### 再出发\n\n按照这个思路,我们将:\n\n```css\n.part2 {\n background-position: 0 -50%;\n}\n```\n\n换算一下将会得到:\n\n```css\n.part2 {\n background-position: 0 50px;\n}\n```\n\n换算过程为:(设置背景的区域高度 - 背景图的高度) \\* -50%,即:(100 - 200) \\* -50% = 50px\n\n这就解释了 `Demo2` 为什么会得到 `图2` 的效果。但这显然并不是我们想要的,我们预期的效果是 `图1`。\n\n根据上述的公式,我们可以逆推预期效果的百分比值是多少:\n\n```\n-100 / (100 - 200) = 100%\n```\n\n所以如果你要使用百分比,那么定义应该是这样的:\n\n```css\n.part2 {\n background-position: 0 100%;\n}\n```\n\n其结果如 `Demo3` [正确使用 background-position 百分比](http://demo.doyoe.com/css3/background-position/percentage-value.htm)\n\n这会终于得到我们的预期效果了,请看 `图3`\n\n![图3:百分比的正确预期效果](http://demo.doyoe.com/css3/background-position/skin/normal.png)\n\n了解了百分比的这个特性后,会帮助我们大大简化某些定义,比如我在 [Yo](https://github.com/doyoe/Yo) 里面对 [yo-score](http://blog.doyoe.com/Yo/demo/element/yo-score.html) 的处理,非常巧妙,有兴趣的童鞋可以自己研究一下,这里不细讲。\n\n另外:需要注意的是百分比值会受 `background-size` 影响,因为 `background-size` 可以改变背景图像的大小。\n\n## 多值\n\n在 `CSS3` 中,对 `background-position` 属性进行了扩展,允许接受3到4个参数,用于指定背景图的起始方向和具体位置。\n\n> 原文:If three or four values are given, then each <percentage> or <length> represents an offset and must be preceded by a keyword, which specifies from which edge the offset is given.\n>\n> 翻译:如果指定了三个或四个值,那么每个 <percentage> 或 <length> 之前必须有一个关键字,用于指定该方向的偏移量。\n\n当指定3到4个参数时,不接受 `center` 关键字作为偏移量作为边界,只能使用 `top, right, bottom, left` 这4个关键字。\n\n### 多值的意义\n\n在此前,我们使用 `background-position` 只能让背景图从 `top, right, bottom, left, center` 这5个边界开始显示,但无法指定任意一个边界的偏移量。\n\n举个例子:我想让一个背景图从右下角偏移 `20px`\n\n你会发现如果没有多值扩展,你很难轻易做到这件事,除非你能确定容器的宽高永远都是显式定义好的,就算如此,其灵活性也一文不值。\n\n### 多值的应用\n\n如果利用多值特性,这将变得非常轻松,我们仍使用 `图0` 作为背景图,来做一个演示。\n\n```\n.demo {\n width: 400px;\n height: 400px;\n background: url(../test.png) no-repeat;\n background-position: right -300px bottom 20px;\n}\n```\n\n这会终于得到我们的预期效果了,请看 `图4`\n\n![图4:背景图多值应用](http://demo.doyoe.com/css3/background-position/skin/multi-value.png)\n\n效果可以查看 `Demo4` [background-position 边界偏移](http://demo.doyoe.com/css3/background-position/multi-value.htm)。实际上,有了多值之后,我们可以让背景图在任意方位上偏移,你可能会发现,这甚至可以让你的结构写得更简单,嵌套变浅。\n\n## 写在最后\n\n当你深入了解了每个属性的每个定义,你的CSS世界又会变得和以前不一样。enjoy it.\n\n\n## background系列文章:\n\n* [background系列之你不知道的background-position](/2016/03/28/css/background系列之你不知道的background-position/)","slug":"css/background系列之你不知道的background-position","published":1,"updated":"2016-03-29T02:39:19.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvahb003l2ypk9ajowuun"},{"title":"BFC如何应用到实际场景","date":"2015-04-12T09:29:00.000Z","author":"杜瑶","private":true,"_content":"\n## 什么是BFC\n\n首先,你可能需要简单的了解一下什么是 `BFC`。\n\nW3C在视觉格式化模型中描述了一个 `Block formatting contexts` 的概念,大致的说法如下:\n\n> 浮动和绝对定位元素,非块盒的块容器(诸如:inline-blocks, table-cells 和 table-captions),以及 `overflow` 值不为 `visiable`(除非该值已经延伸到视口上) 的块盒,都会为他们的内容创建新的块格式化上下文。\n\n> 在一个块格式化上下文里,盒子从包含块顶部开始一个接一个的纵向排列。两个相邻兄弟盒子之间的垂直的间隙取决于 `margin` 定义。块级盒纵向相邻(水平书写格式下)的 `margins` 会在同一个块格式化上下文中折叠合并(取最大值)。\n\n> 在一个块格式化上下文里,每个盒子的左外边界会触碰到包含块的左边界(如果是从右到左的书写格式,则为右边界),即使同时存在浮动元素也是如此(虽然盒子的行框集可能会由于浮动的存在而缩小),除非这个盒子创建了一个新的块格式化上下文(在这种情况下,盒子本身由于浮动可能会变得更窄)。\n\n这其实就是对于 `BFC` 的描述,也即大家常说的块格式化上下文,所以 `BFC` 没什么神秘的,只是 `Block formatting contexts` 的首字母缩写。\n\n题外话:一个简单的概念,被各种 `名词再造`,不知道在什么时候突然成为了一个高大上的东西。以下省略2个字:讨厌。\n\n为了方便理解,也为了符合大家的认知习惯,这个概念在下面都以 `BFC` 来代替。\n\n<!--more-->\n\n## Formatting context 的作用\n\n待补充。。。","source":"_posts/css/BFC如何应用到实际场景.md","raw":"title: BFC如何应用到实际场景\ndate: 2015-04-12 17:29:00\ncategories: CSS\nauthor: 杜瑶\ntags: [w3c, BFC]\nprivate: true\n---\n\n## 什么是BFC\n\n首先,你可能需要简单的了解一下什么是 `BFC`。\n\nW3C在视觉格式化模型中描述了一个 `Block formatting contexts` 的概念,大致的说法如下:\n\n> 浮动和绝对定位元素,非块盒的块容器(诸如:inline-blocks, table-cells 和 table-captions),以及 `overflow` 值不为 `visiable`(除非该值已经延伸到视口上) 的块盒,都会为他们的内容创建新的块格式化上下文。\n\n> 在一个块格式化上下文里,盒子从包含块顶部开始一个接一个的纵向排列。两个相邻兄弟盒子之间的垂直的间隙取决于 `margin` 定义。块级盒纵向相邻(水平书写格式下)的 `margins` 会在同一个块格式化上下文中折叠合并(取最大值)。\n\n> 在一个块格式化上下文里,每个盒子的左外边界会触碰到包含块的左边界(如果是从右到左的书写格式,则为右边界),即使同时存在浮动元素也是如此(虽然盒子的行框集可能会由于浮动的存在而缩小),除非这个盒子创建了一个新的块格式化上下文(在这种情况下,盒子本身由于浮动可能会变得更窄)。\n\n这其实就是对于 `BFC` 的描述,也即大家常说的块格式化上下文,所以 `BFC` 没什么神秘的,只是 `Block formatting contexts` 的首字母缩写。\n\n题外话:一个简单的概念,被各种 `名词再造`,不知道在什么时候突然成为了一个高大上的东西。以下省略2个字:讨厌。\n\n为了方便理解,也为了符合大家的认知习惯,这个概念在下面都以 `BFC` 来代替。\n\n<!--more-->\n\n## Formatting context 的作用\n\n待补充。。。","slug":"css/BFC如何应用到实际场景","published":1,"updated":"2016-03-29T02:40:43.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvahf003s2ypkss5xcu3a"},{"title":"移动前端第三弹:这样简单的理解屏幕适配","date":"2016-02-23T08:00:11.000Z","author":"杜瑶","_content":"\n## 前言\n\n我一直在想办法让大家可以轻松的知道如何去做一个屏幕适配,不过众多的概念,却是让人越看越晕,越细究越迷糊。\n\n或许我可以从一个实际的现状去做解释,然后将一些概念透明,可能会有助于理解。\n\n## Why 640px\n\n如果你开始了`Web App`的开发,我相信,你总能从设计师那里拿到宽度为`640px`的设计稿。\n\n我猜很多人都已经知道这个值是怎么来的,但这并不妨碍我们再来做一次重复的解释。\n\n`640px`的来由是设计师以`iPhone`作为参照标的①,请看下图:`Figure 1`\n\n> ①当然,对于为什么设计师会选择`iPhone`作为参照,我没有寻根问源过,可能大部分设计师也说不清,只是因为其他人都这么干,慢慢都这样了。所以你可以去找到第一个这么做的人\n\n![Figure 1: iPhone4 screen width](/image/adapter/iphone.png)\n\n从图中能看到`iPhone4`纵向时的`Screen width`(这里说的并不是Screen size②)屏幕宽度为`320px`,似乎设计稿的宽度也应该是`320px`才对?\n\n> ②Screen size\n> 通常来讲,我们说的`Screen size`(屏幕尺寸)都是指设备屏幕对角线测量的实际长度,比如:iPhone4是3.5″,iphone5是4″,iphone6是4.7″,iPhone6 Plus是5.5″","source":"_drafts/移动前端第三弹:这样简单的理解屏幕适配.md","raw":"title: 移动前端第三弹:这样简单的理解屏幕适配\ndate: 2016-2-23 16:00:11\nauthor: 杜瑶\ncategories: mobile\ntags: [HTML5, 设备像素比, devicePixelRatio, DIP, 设备独立像素, physical pixel, 物理像素, PPI, 每英寸像素量]\n---\n\n## 前言\n\n我一直在想办法让大家可以轻松的知道如何去做一个屏幕适配,不过众多的概念,却是让人越看越晕,越细究越迷糊。\n\n或许我可以从一个实际的现状去做解释,然后将一些概念透明,可能会有助于理解。\n\n## Why 640px\n\n如果你开始了`Web App`的开发,我相信,你总能从设计师那里拿到宽度为`640px`的设计稿。\n\n我猜很多人都已经知道这个值是怎么来的,但这并不妨碍我们再来做一次重复的解释。\n\n`640px`的来由是设计师以`iPhone`作为参照标的①,请看下图:`Figure 1`\n\n> ①当然,对于为什么设计师会选择`iPhone`作为参照,我没有寻根问源过,可能大部分设计师也说不清,只是因为其他人都这么干,慢慢都这样了。所以你可以去找到第一个这么做的人\n\n![Figure 1: iPhone4 screen width](/image/adapter/iphone.png)\n\n从图中能看到`iPhone4`纵向时的`Screen width`(这里说的并不是Screen size②)屏幕宽度为`320px`,似乎设计稿的宽度也应该是`320px`才对?\n\n> ②Screen size\n> 通常来讲,我们说的`Screen size`(屏幕尺寸)都是指设备屏幕对角线测量的实际长度,比如:iPhone4是3.5″,iphone5是4″,iphone6是4.7″,iPhone6 Plus是5.5″","slug":"移动前端第三弹:这样简单的理解屏幕适配","published":0,"updated":"2016-02-23T08:05:24.000Z","comments":1,"layout":"post","photos":[],"link":"","_id":"cinjqvahi003x2ypkd0lerx80"}],"PostAsset":[],"PostCategory":[{"post_id":"cinjqvafq00032ypka7qu3u8h","category_id":"cinjqvafu00042ypk22zb1u2c","_id":"cinjqvafw00072ypkbp7jsz2i"},{"post_id":"cinjqvafy000e2ypk2aar6u68","category_id":"cinjqvafu00042ypk22zb1u2c","_id":"cinjqvafz000f2ypktev0eawx"},{"post_id":"cinjqvag1000k2ypks1ixuept","category_id":"cinjqvag2000l2ypk2hojf81x","_id":"cinjqvag3000o2ypkfxps5h63"},{"post_id":"cinjqvag5000r2ypkt9h8j2de","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvag6000v2ypkwej7sfhl"},{"post_id":"cinjqvag700102ypkytcqoiv5","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvag800112ypk2xx0ai09"},{"post_id":"cinjqvaga00182ypkypfsleum","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvagb00192ypktm2a02ox"},{"post_id":"cinjqvagd001f2ypknqlrfofi","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvage001g2ypkdh1ou0y9"},{"post_id":"cinjqvagg001m2ypkivnatu8j","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvagh001n2ypk4x6q7pcm"},{"post_id":"cinjqvagk001w2ypkeljv8cye","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvagl001x2ypk95shqbsj"},{"post_id":"cinjqvagm00222ypkms8jz73c","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvagn00232ypkjanb8m2g"},{"post_id":"cinjqvago00292ypkgmxah41e","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvagp002a2ypkrqsqosr2"},{"post_id":"cinjqvagr002f2ypk7x2e9sgr","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvags002g2ypkjecsglx5"},{"post_id":"cinjqvagu002k2ypkuu7kcua5","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvagv002l2ypk0wpdztwl"},{"post_id":"cinjqvagw002q2ypk8thgeeu5","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvagx002r2ypkah0elxze"},{"post_id":"cinjqvagz002u2ypkwojbowh6","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvah0002v2ypkw987q9ez"},{"post_id":"cinjqvah200302ypkeso0e7tu","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvah300312ypkmt3cvjwe"},{"post_id":"cinjqvah400352ypki5fkxxjp","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvah600362ypkd9wxlk4g"},{"post_id":"cinjqvah8003a2ypkhiuzsz5i","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvah9003b2ypk3dr8nwmq"},{"post_id":"cinjqvahb003l2ypk9ajowuun","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvahc003m2ypkn3vx9b7r"},{"post_id":"cinjqvahf003s2ypkss5xcu3a","category_id":"cinjqvag5000s2ypkn7t4myl4","_id":"cinjqvahg003t2ypk7yhxf51x"},{"post_id":"cinjqvahi003x2ypkd0lerx80","category_id":"cinjqvafu00042ypk22zb1u2c","_id":"cinjqvahj003y2ypk9w8sy63o"}],"PostTag":[{"post_id":"cinjqvafq00032ypka7qu3u8h","tag_id":"cinjqvafu00052ypkaczhwsis","_id":"cinjqvafx000a2ypk51p1ll02"},{"post_id":"cinjqvafq00032ypka7qu3u8h","tag_id":"cinjqvafw00062ypkqym7hi9d","_id":"cinjqvafx000b2ypkb1ym7v08"},{"post_id":"cinjqvafq00032ypka7qu3u8h","tag_id":"cinjqvafw00082ypknki6pweo","_id":"cinjqvafx000c2ypkc0kv1xs7"},{"post_id":"cinjqvafq00032ypka7qu3u8h","tag_id":"cinjqvafw00092ypkg53d5s8z","_id":"cinjqvafx000d2ypks7ky0i2z"},{"post_id":"cinjqvafy000e2ypk2aar6u68","tag_id":"cinjqvafu00052ypkaczhwsis","_id":"cinjqvag0000h2ypkeb42wxyh"},{"post_id":"cinjqvafy000e2ypk2aar6u68","tag_id":"cinjqvag0000g2ypk8ra9edpb","_id":"cinjqvag0000i2ypkgf320rkw"},{"post_id":"cinjqvafy000e2ypk2aar6u68","tag_id":"cinjqvafw00062ypkqym7hi9d","_id":"cinjqvag0000j2ypkt2ogleuv"},{"post_id":"cinjqvag1000k2ypks1ixuept","tag_id":"cinjqvag3000m2ypk2bvqlyeg","_id":"cinjqvag3000p2ypkzwf9kpl3"},{"post_id":"cinjqvag1000k2ypks1ixuept","tag_id":"cinjqvag3000n2ypk1sikoypo","_id":"cinjqvag3000q2ypkhtgc39sb"},{"post_id":"cinjqvag5000r2ypkt9h8j2de","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvag6000x2ypkj5zpgyeb"},{"post_id":"cinjqvag5000r2ypkt9h8j2de","tag_id":"cinjqvag6000u2ypkefgcw7o5","_id":"cinjqvag6000y2ypkbpt6fzjp"},{"post_id":"cinjqvag5000r2ypkt9h8j2de","tag_id":"cinjqvag6000w2ypks26l3lvw","_id":"cinjqvag6000z2ypkzaahdgog"},{"post_id":"cinjqvag700102ypkytcqoiv5","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvag900142ypkd9khkp0p"},{"post_id":"cinjqvag700102ypkytcqoiv5","tag_id":"cinjqvag6000u2ypkefgcw7o5","_id":"cinjqvag900152ypkiga64rh8"},{"post_id":"cinjqvag700102ypkytcqoiv5","tag_id":"cinjqvag800122ypkqnz8b14d","_id":"cinjqvag900162ypktolxuagf"},{"post_id":"cinjqvag700102ypkytcqoiv5","tag_id":"cinjqvag900132ypk9nqdx9l4","_id":"cinjqvag900172ypk4unvt1pc"},{"post_id":"cinjqvaga00182ypkypfsleum","tag_id":"cinjqvagc001a2ypk5dmiyqjl","_id":"cinjqvagc001c2ypkela25neb"},{"post_id":"cinjqvaga00182ypkypfsleum","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvagc001d2ypktdyuu9zu"},{"post_id":"cinjqvaga00182ypkypfsleum","tag_id":"cinjqvagc001b2ypk0x6p4vkh","_id":"cinjqvagc001e2ypkfv5v83lx"},{"post_id":"cinjqvagd001f2ypknqlrfofi","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvagf001j2ypke9w5n18m"},{"post_id":"cinjqvagd001f2ypknqlrfofi","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvagf001k2ypkr31hl6mx"},{"post_id":"cinjqvagd001f2ypknqlrfofi","tag_id":"cinjqvage001i2ypkrt6tfwnm","_id":"cinjqvagf001l2ypkrtkvr7f0"},{"post_id":"cinjqvagg001m2ypkivnatu8j","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvagi001r2ypkcxswj7dz"},{"post_id":"cinjqvagg001m2ypkivnatu8j","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvagj001s2ypkc8av5tqd"},{"post_id":"cinjqvagg001m2ypkivnatu8j","tag_id":"cinjqvagi001o2ypkjja3vek0","_id":"cinjqvagj001t2ypk0s4494yi"},{"post_id":"cinjqvagg001m2ypkivnatu8j","tag_id":"cinjqvagi001p2ypk8ctrpmbr","_id":"cinjqvagj001u2ypkymrwsrzl"},{"post_id":"cinjqvagg001m2ypkivnatu8j","tag_id":"cinjqvagi001q2ypkeqbzf1b9","_id":"cinjqvagj001v2ypk0hchr1tq"},{"post_id":"cinjqvagk001w2ypkeljv8cye","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvagl001z2ypkia5np8wy"},{"post_id":"cinjqvagk001w2ypkeljv8cye","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvagl00202ypk5xf79gac"},{"post_id":"cinjqvagk001w2ypkeljv8cye","tag_id":"cinjqvagl001y2ypk9f7cl9gf","_id":"cinjqvagl00212ypkrn9qpx6k"},{"post_id":"cinjqvagm00222ypkms8jz73c","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvagn00242ypkttwolgfy"},{"post_id":"cinjqvagm00222ypkms8jz73c","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvagn00252ypk39korv37"},{"post_id":"cinjqvagm00222ypkms8jz73c","tag_id":"cinjqvagi001o2ypkjja3vek0","_id":"cinjqvagn00262ypk33ygmydk"},{"post_id":"cinjqvagm00222ypkms8jz73c","tag_id":"cinjqvagi001p2ypk8ctrpmbr","_id":"cinjqvagn00272ypkijr3xzeo"},{"post_id":"cinjqvagm00222ypkms8jz73c","tag_id":"cinjqvagi001q2ypkeqbzf1b9","_id":"cinjqvagn00282ypkkxck22zv"},{"post_id":"cinjqvago00292ypkgmxah41e","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvagq002c2ypkgioszqiv"},{"post_id":"cinjqvago00292ypkgmxah41e","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvagq002d2ypkaj25rt0d"},{"post_id":"cinjqvago00292ypkgmxah41e","tag_id":"cinjqvagq002b2ypkfsskq1xw","_id":"cinjqvagq002e2ypkv6j03df7"},{"post_id":"cinjqvagr002f2ypk7x2e9sgr","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvagt002h2ypke0pazpv2"},{"post_id":"cinjqvagr002f2ypk7x2e9sgr","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvagt002i2ypk2l8dnhda"},{"post_id":"cinjqvagr002f2ypk7x2e9sgr","tag_id":"cinjqvagq002b2ypkfsskq1xw","_id":"cinjqvagt002j2ypk6k0fnys5"},{"post_id":"cinjqvagu002k2ypkuu7kcua5","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvagv002n2ypk217b2n74"},{"post_id":"cinjqvagu002k2ypkuu7kcua5","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvagv002o2ypkztgwq9sj"},{"post_id":"cinjqvagu002k2ypkuu7kcua5","tag_id":"cinjqvagv002m2ypkum6uiwb1","_id":"cinjqvagv002p2ypkb1urkxxv"},{"post_id":"cinjqvagw002q2ypk8thgeeu5","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvagx002s2ypk99rq5pzs"},{"post_id":"cinjqvagw002q2ypk8thgeeu5","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvagx002t2ypkau6f8ln8"},{"post_id":"cinjqvagz002u2ypkwojbowh6","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvah1002x2ypknhwstdoc"},{"post_id":"cinjqvagz002u2ypkwojbowh6","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvah1002y2ypksot32ycy"},{"post_id":"cinjqvagz002u2ypkwojbowh6","tag_id":"cinjqvah0002w2ypkzcc8g8sw","_id":"cinjqvah1002z2ypkqj0fzfqh"},{"post_id":"cinjqvah200302ypkeso0e7tu","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvah300322ypkth2nteuk"},{"post_id":"cinjqvah200302ypkeso0e7tu","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvah300332ypkakrxzbht"},{"post_id":"cinjqvah200302ypkeso0e7tu","tag_id":"cinjqvah0002w2ypkzcc8g8sw","_id":"cinjqvah300342ypkc92u5scg"},{"post_id":"cinjqvah400352ypki5fkxxjp","tag_id":"cinjqvage001h2ypkw7ulj3aq","_id":"cinjqvah600372ypktnkh6z6v"},{"post_id":"cinjqvah400352ypki5fkxxjp","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvah600382ypkulxzod2t"},{"post_id":"cinjqvah400352ypki5fkxxjp","tag_id":"cinjqvah0002w2ypkzcc8g8sw","_id":"cinjqvah600392ypkcqgh5u1g"},{"post_id":"cinjqvah8003a2ypkhiuzsz5i","tag_id":"cinjqvah9003c2ypkfukft6zk","_id":"cinjqvaha003g2ypknr6biodc"},{"post_id":"cinjqvah8003a2ypkhiuzsz5i","tag_id":"cinjqvaha003d2ypkhtss6bch","_id":"cinjqvaha003h2ypk70o8odf8"},{"post_id":"cinjqvah8003a2ypkhiuzsz5i","tag_id":"cinjqvaha003e2ypkhw8kakg8","_id":"cinjqvaha003i2ypk6u2eldsb"},{"post_id":"cinjqvah8003a2ypkhiuzsz5i","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvahb003j2ypkjt3h9w9w"},{"post_id":"cinjqvah8003a2ypkhiuzsz5i","tag_id":"cinjqvaha003f2ypk5gu37rhs","_id":"cinjqvahb003k2ypkfzcj6egf"},{"post_id":"cinjqvahb003l2ypk9ajowuun","tag_id":"cinjqvah9003c2ypkfukft6zk","_id":"cinjqvahd003o2ypkfza92ld5"},{"post_id":"cinjqvahb003l2ypk9ajowuun","tag_id":"cinjqvahd003n2ypkismub4j7","_id":"cinjqvahd003p2ypkg8q7a7rc"},{"post_id":"cinjqvahb003l2ypk9ajowuun","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvahd003q2ypk4tvchxzb"},{"post_id":"cinjqvahb003l2ypk9ajowuun","tag_id":"cinjqvaha003f2ypk5gu37rhs","_id":"cinjqvahd003r2ypktgu1d5yr"},{"post_id":"cinjqvahf003s2ypkss5xcu3a","tag_id":"cinjqvag5000t2ypkgj4d3pag","_id":"cinjqvahh003v2ypkzbjt5097"},{"post_id":"cinjqvahf003s2ypkss5xcu3a","tag_id":"cinjqvahh003u2ypk061d5pgu","_id":"cinjqvahh003w2ypkr3vd5qmd"},{"post_id":"cinjqvahi003x2ypkd0lerx80","tag_id":"cinjqvafu00052ypkaczhwsis","_id":"cinjqvahr00472ypkpl6az7dx"},{"post_id":"cinjqvahi003x2ypkd0lerx80","tag_id":"cinjqvahj003z2ypkr8qnz4u2","_id":"cinjqvahr00482ypkqn4589g3"},{"post_id":"cinjqvahi003x2ypkd0lerx80","tag_id":"cinjqvahj00402ypks8ug462o","_id":"cinjqvahr00492ypkzupcc7lg"},{"post_id":"cinjqvahi003x2ypkd0lerx80","tag_id":"cinjqvahj00412ypkxmoiwnxc","_id":"cinjqvahr004a2ypk9414y1sb"},{"post_id":"cinjqvahi003x2ypkd0lerx80","tag_id":"cinjqvahj00422ypk8po5oeur","_id":"cinjqvahr004b2ypkytbia6sf"},{"post_id":"cinjqvahi003x2ypkd0lerx80","tag_id":"cinjqvahk00432ypka0oqnnvz","_id":"cinjqvahr004c2ypkm5uwi7v6"},{"post_id":"cinjqvahi003x2ypkd0lerx80","tag_id":"cinjqvahq00442ypk91z21bqs","_id":"cinjqvahr004d2ypkd4oll74p"},{"post_id":"cinjqvahi003x2ypkd0lerx80","tag_id":"cinjqvahr00452ypk5fkvktbd","_id":"cinjqvahr004e2ypkmvefjwl4"},{"post_id":"cinjqvahi003x2ypkd0lerx80","tag_id":"cinjqvahr00462ypkyfutaup1","_id":"cinjqvahr004f2ypkmz6z2rwt"}],"Tag":[{"name":"HTML5","_id":"cinjqvafu00052ypkaczhwsis"},{"name":"meta","_id":"cinjqvafw00062ypkqym7hi9d"},{"name":"meta大全","_id":"cinjqvafw00082ypknki6pweo"},{"name":"meta列表","_id":"cinjqvafw00092ypkg53d5s8z"},{"name":"viewport","_id":"cinjqvag0000g2ypk8ra9edpb"},{"name":"随笔","_id":"cinjqvag3000m2ypk2bvqlyeg"},{"name":"生活","_id":"cinjqvag3000n2ypk1sikoypo"},{"name":"w3c","_id":"cinjqvag5000t2ypkgj4d3pag"},{"name":"视觉格式化模型","_id":"cinjqvag6000u2ypkefgcw7o5"},{"name":"包含块","_id":"cinjqvag6000w2ypks26l3lvw"},{"name":"非置换元素","_id":"cinjqvag800122ypkqnz8b14d"},{"name":"置换元素","_id":"cinjqvag900132ypk9nqdx9l4"},{"name":"z-index","_id":"cinjqvagc001a2ypk5dmiyqjl"},{"name":"层叠上下文","_id":"cinjqvagc001b2ypk0x6p4vkh"},{"name":"margin","_id":"cinjqvage001h2ypkw7ulj3aq"},{"name":"margin百分比","_id":"cinjqvage001i2ypkrt6tfwnm"},{"name":"margin layout","_id":"cinjqvagi001o2ypkjja3vek0"},{"name":"圣杯布局","_id":"cinjqvagi001p2ypk8ctrpmbr"},{"name":"holy grail","_id":"cinjqvagi001q2ypkeqbzf1b9"},{"name":"margin折叠","_id":"cinjqvagl001y2ypk9f7cl9gf"},{"name":"margin应用","_id":"cinjqvagq002b2ypkfsskq1xw"},{"name":"margin偏移","_id":"cinjqvagv002m2ypkum6uiwb1"},{"name":"margin bug","_id":"cinjqvah0002w2ypkzcc8g8sw"},{"name":"background","_id":"cinjqvah9003c2ypkfukft6zk"},{"name":"background-origin","_id":"cinjqvaha003d2ypkhtss6bch"},{"name":"gradient","_id":"cinjqvaha003e2ypkhw8kakg8"},{"name":"CSS应用","_id":"cinjqvaha003f2ypk5gu37rhs"},{"name":"background-position","_id":"cinjqvahd003n2ypkismub4j7"},{"name":"BFC","_id":"cinjqvahh003u2ypk061d5pgu"},{"name":"设备像素比","_id":"cinjqvahj003z2ypkr8qnz4u2"},{"name":"devicePixelRatio","_id":"cinjqvahj00402ypks8ug462o"},{"name":"DIP","_id":"cinjqvahj00412ypkxmoiwnxc"},{"name":"设备独立像素","_id":"cinjqvahj00422ypk8po5oeur"},{"name":"physical pixel","_id":"cinjqvahk00432ypka0oqnnvz"},{"name":"物理像素","_id":"cinjqvahq00442ypk91z21bqs"},{"name":"PPI","_id":"cinjqvahr00452ypk5fkvktbd"},{"name":"每英寸像素量","_id":"cinjqvahr00462ypkyfutaup1"}]}}