nodejs github api 测试

var github = require('github');

var api = new github({
    version: '3.0.0',
    debug: false,
    protocol: 'https',
    host: 'api.github.com',
    timeout: 5000,
    headers: {
        'user-agent': 'BaiduSpider'
    }
});

api.authenticate({
    type: "basic",
    username: 'github账号',
    password: 'github密码'
});

/* 创建
api.repos.createContent({
    user: 'w3hacker',
    repo: 'test',
    content: new Buffer('I am content').toString('base64'),
    message: 'I am message',
    path: 'test.md'
}, function(err, result) {
    console.log(arguments);
});
*/

/* 获取项目主目录文件个数
api.repos.getContent({
    user: 'w3hacker',
    repo: 'mqtt-android-service',
    path: ''
}, function(err, result) {
    console.log(result.length);
});
*/

/* 创建、上传文件
var fs = require('fs');

api.repos.createFile({
    user: 'w3hacker',
    repo: 'test',
    path: 'org.eclipse.paho.android.service-1.0.3-20150427.040641-68-sources.jar',
    message: 'commit message',
    content: new Buffer(fs.readFileSync('org.eclipse.paho.android.service-1.0.3-20150427.040641-68-sources.jar', 'utf-8')).toString('base64')
}, function(err, result) {
    console.log(arguments);
});
*/

 

发表在 nodejs | 留下评论

github SHA1算法

This is how Git calculates the SHA1 for a file (or, in Git terms, a “blob”):

sha1("blob " + filesize + "\0" + data)

So you can easily compute it yourself without having Git installed. Note that “\0″ is the NULL-byte, not a two-character string.

For example, the hash of an empty file:

sha1("blob 0\0") = "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"

$ touch empty
$ git hash-object empty
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391

Another example:

sha1("blob 7\0foobar\n") = "323fae03f4606ea9991df8befbb2fca795e648fa"

$ echo "foobar" > foo.txt
$ git hash-object foo.txt 
323fae03f4606ea9991df8befbb2fca795e648fa

Here is a Python implementation:

from hashlib import sha1
def githash(data):
    s = sha1()
    s.update("blob %u\0" % len(data))
    s.update(data)
    return s.hexdigest()
发表在 Linux | 留下评论

github文件获取sha

curl https://api.github.com/repos/w3hacker/test/contents/test.md

参考链接:

http://stackoverflow.com/questions/20207594/how-to-find-a-github-file-s-sha-blob

发表在 Linux | 留下评论

gulp + browserSync + sass

var gulp        = require('gulp');
var browserSync = require('browser-sync').create();
var sass        = require('gulp-sass');
var reload      = browserSync.reload;

// Static Server + watching scss/html files
gulp.task('serve', ['sass'], function() {

    browserSync.init({
        server: "./"
    });

    gulp.watch("scss/*.scss", ['sass']);
    gulp.watch("*.html").on('change', reload);
});

// Compile sass into CSS & auto-inject into browsers
gulp.task('sass', function() {
    return gulp.src("scss/*.scss")
        .pipe(sass())
        .pipe(gulp.dest("css"))
        .pipe(reload({stream: true}));
});

gulp.task('default', ['serve']);

 

发表在 前端技术 | 留下评论

Get SASS Working in Sublime Text for Windows in 8 Steps

Compile SASS, Sublime Text Windows

Follow these installation instructions to start using SASS with Sublime Text. You’ll be able to save your SASS (.scss) file, and it will compile to a CSS file automatically. There are a few more extensive guides out there on this, but they skipped over a few minor things that you may miss.  This boils it down to the essentials that you need to get up and running.

How to Build .scss with Sublime Text:

  1. Install Ruby: Download Ruby for Windows. When you run the installer, choose the option Executable in PATH
  2. Install SASS with Ruby: Open your Start menu and type “cmd” to open a command prompt. Type “gem install sass” and press enter. Gem will do its thing and install.
  3. Install Package Manager for Sublime Text: You may already have this installed if you’ve been installing other extensions. Follow the installation instructions on the plugin’s website.
  4. Use Package Manager to Install “SASS”: This package is for syntax highlighting. Open the command panel with Ctrl+Shift+P and run “Package Control: Install Package”, then type SASS to find the package to install and press Enter.
    • There probably is a conflict where the syntax highlighter thinks your files are HAML. Rather than modifying your Ruby highlighting settings as some articles show, you can do this when you have an .scss/.sass file open:
      View -> Syntax -> Open all with current extension as … | Sass
  5. Use Package Manager to Install “SASS Build”: This will allow your SASS/SCSS files to be compiled.
  6. (Optional) Use Package Manager to Install “SublimeOnSaveBuild”: Use this if you want to compile whenever you save, rather than using the separate keyboard shortcut for build (Ctrl+B).
  7. Restart Sublime Text
  8. Save your .scss file, and voila, the corresponding .css file of the same name will appear in the directory.

Helpful Hints:

  • Don’t want the CSS file to save in the same directory? If you want to change the default folder that your generated CSS files are saved to, you can edit the configuration for what Sublime Text calls “Build Systems”. This configuration is what’s calling the commandline for SASS. Unfortunately there doesn’t appear to be a way to do this on a per-project basis, but you can change it.Example I used for WordPress: Having style.scss in the folder /sass/ inside your theme folder, this would save style.css in the root.
    "cmd": ["sass", "--update", "$file:${file_path}/../${file_base_name}.css"],
  • You probably don’t want your SASS partials to be compiled, if you’re using the SublimeOnSaveBuild. I’ve wrote another blog about adding a regex to stop this.

Package Links:

发表在 前端技术 | 留下评论

angular 常用第三方组件

angular-ui/bootstrap
https://github.com/angular-ui/bootstrap

ui-router
https://github.com/angular-ui/ui-router

bindonce (单向绑定 减少资源占用)
https://github.com/Pasvaz/bindonce

angular-growl (简单的消息提醒)
https://github.com/marcorinck/angular-growl

angular-base64 (angular的base64实现)
https://github.com/ninjatronic/angular-base64

angular-translate (angular多语言支持)
https://github.com/angular-translate/angular-translate

ngAnimate (angular动画库)
http://augus.github.io/ngAnimate/

发表在 angularJS | 留下评论

过油肉土豆片

QQ20150415-1@2x

  • 1

    猪里脊切片,打入一个鸡蛋清

  • 2

    再放入玉米淀粉,老抽,盐,料酒

  • 3

    用手抓匀,待用

  • 4

    准备好原料:土豆去皮,木耳提前发泡好,尖椒和彩椒洗净,葱姜蒜去皮洗净

  • 5

    将土豆切片,厚度3MM,凉水冲洗后沥干水份(是为了防止土豆遇到空气氧化成黑色和油炸时防止粘连)

  • 6

    尖椒,彩椒切菱形块,木耳撕成小块

  • 7

    葱姜蒜切片

  • 8

    锅里放油,烧到六成热,放入土豆片开始炸

  • 9

    炸至金黄色,捞出控油

  • 10

    六成热的油温,放入尖椒片,马上捞出控油

  • 11

    六成热的油温,滑熟腌制好的里脊肉

  • 12

    锅里放少许油,放入葱姜蒜片煸香

  • 13

    放入彩椒块和木耳,放盐和花椒面,翻炒

  • 14

    放入过油肉

  • 15

    放入炸好的土豆片

  • 16

    再放炸过的尖椒块

  • 17

    放少许盐,老抽,醋,高汤,少许水淀粉勾芡

  • 18

    装盘,鲜香可口,下饭菜首选哦

发表在 菜谱 | 留下评论

Understanding CSS Floats

Using css floats effectively can be confusing and it’s probably one of the things that trips up most people when they’re first learning css. However once you learn to control floated elements it opens up a whole new world of possibilities in your design and makes developing layouts much simpler.

And best of all floats really aren’t that hard to work with once you understand a few key points.

What is a Float?

A float is a box that is shifted to the left or right on the current line. The most interesting characteristic of a float (or “floated” or “floating” box) is that content may flow along its side (or be prohibited from doing so by the ‘clear’ property).
w3.org

The float property has 3 values; none, which is the default, left, and right. As much as you might wish it so there is no center value. Horizontal centering in css is accomplished through margins.

Floats sit as far left or as far right as possible within the immediate containing div. Depending upon the available width where a float is declared, other elements can sit next to a floated element or flow around it.

The Difference Between Floats and Positioning

In css there are 3 types of positioning schemes. From w3.org

  1. Normal flow – In CSS 2.1, normal flow includes block formatting of block boxes, inline formatting of inline boxes, relative positioning of block or inline boxes, and positioning of run-in boxes.
  2. Floats – In the float model, a box is first laid out according to the normal flow, then taken out of the flow and shifted to the left or right as far as possible. Content may flow along the side of a float.
  3. Absolute positioning – In the absolute positioning model, a box is removed from the normal flow entirely (it has no impact on later siblings) and assigned a position with respect to a containing block.

Relative positioning shifts elements relative to their position in the normal document flow. Other elements are not affected and lay where they would had no positioning been applied. This leads to the possibility that elements with relative positioning may overlap surrounding elements on the page.

Note that floats are taken out of the normal document flow, but floats do affect the position of elements around them.

How to Effectively Use Floats

There are two main ways floats are used.

Text Flowing Around An Image

Images are the most common, but you can substitute a different element. The idea is that text will wrap around some element.

wrapping-float.png

This was the original intention of the floated element. You float an element left or right and allow other elements, usually text to flow or wrap around the element. When using floats in this fashion you want to have both the floated element and the wrapping text inside the same containing element.

1
2
3
4
<p>
<img class="alignleft" src="" alt="" width="" height="" />
Lots of text here. Enough to wrap around the image.
</p>
1
img.alignleft {float: left; margin: 0 10px 10px 0}

In the above code both the floated element and the wrapping text are contained within the same paragraph.

Notice that in the css I’ve added a right and bottom margin. It’s good practice when floating an image to add a little space between it and the wrapping text. Left floated images get a right margin and right floated images get a left margin. Both have a margin added to the bottom. 10px is arbitrary and you could use padding instead of margins if you choose.

Column Layouts

Because floats allow two block level elements (such as divs) to sit up against each other, it’s easy to use them to create columns.

1
2
3
4
<div id="wrapper">
  <div id="left-column"></div>
  <div id="right-column"></div>
</div>
1
2
#left-column {float: left}
#right-column {float: left}

Float both column divs above to the left and you have two columns. You would also need to make sure the combined widths of the two column divs can fit inside the width of the wrapper div. Alternately you can float the right column to the right, but I usually prefer floating both in the same direction.

Add a header div above the two columns and a footer (with the clear property applied) below and you have a nice and simple 2 column css layout.

2-column-layout.png

One last tip when floating an element. Always set a width on the floated element. Not setting one could have unintended consequences.

Clearing Floats

Often with floats you’ll want to ensure an element that follows one or more floated elements sits below those floated elements. The solution is the css clear property.

Clear takes the values left, right, both, none (default), and inherit. In practice you’ll only use the first 3 and most of the time you’ll use clear: both.

Perhaps the most common use is to clear your footer div so it sits below your 2 or 3 floated columns.

cleared.png

not-cleared.png

Containing Floats

The first thing to consider when containing floats is to make sure the containing element is wide enough to hold the floated elements you want to sit next to each other. If you float two elements left in order to create a two column layout and the combined with of the floats is greater than the width of the containing element, one of the floated elements will drop to the next line.

float-drop-left.png

float-drop-right.png

I mentioned above that floated elements are taken out of the normal document flow. This leads to an interesting and confusing issue when all the elements inside a containing element are floated.

A common place you might see this is when you have a header div and the only elements inside is a logo image which you float left. You also apply a css background-image to the header, but it doesn’t show up.

The issue is that the header div contains the single floated image and and because that image is no longer in the normal document flow, the header div considers itself to be empty and has no height. The containing div has essentially collapsed on itself. There are a few ways to deal with this problem.

You could explicitly set a height on the container div. This would work fine in the header example above, but may not be feasible in all cases of collapsed containers. Sometimes you’ll want to add an empty div that you clear below the floated elements.

1
<div class="clear"></div>

This works well if it’s ok to have a little extra space below the floated elements. Some browsers may apply a default height, margin, padding, etc. to the empty div.

The last method is to use the overflow property on the containing element. You’ll generally use overflow: hidden, but depending on your situation you may prefer to use overflow: auto or use overflow-y instead of using it in both directions. Overflow prevents the containing element from collapsing.

Issues With Floats

In addition to collapsing containers there are a few issues with floats to be aware of.

Older versions of IE have a double margin bug. If you float an element in one direction and also add a margin on the element in the same direction (left/left or right/right), IE doubles the margin.

A simple solution is to set display: inline on the floated element. Alternatively you can use conditional comments to set a different margin for IE or for a specific version of IE.

Another common issue is adding elements inside a floated element whose width is wider than the width of the floated element. You might for example add an image inside a floated div and the image is wider than the div itself.

Depending on the browser this could lead to your floated element being wider than you intended or it could lead to content overlapping your image. Make sure elements inside a floated element aren’t wider than the floated element.

One last issue to look out for is that of the disappearing bottom margin. The bottom margin of a floated element inside another floated elements might be ignored. The simple solution is to use padding instead of margin when that happens.

Summary

When people first learn css they tend to gravitate toward absolute and relative positioning for layouts, since both seem simpler on the surface. It’s generally better practice to use floats and if you remember a few key points you should be able to understand and to control floated elements in your layout.

  • Floats are laid out in normal document flow and then shifted as far left or right within containing elements and removed from normal document flow.
  • Elements can flow around floated elements as long as there is enough horizontal space to contain them. If there’s not enough space the elements will display below the floated element
  • Floats and positioned elements are different and behave in different ways. You can’t apply both to the same element.
  • Use floats when you want text to flow around an element or to create columns in a layout
  • Remember to clear elements that you want to fall below floated elements and to keep containing element from collapsing
  • Find solutions you’re comfortable with to a few common float issues in Internet Explorer

I hope the above helps clear up some of the confusion you might have using css floats. If you have more questions about them please ask and I’ll do my best to answer. Here are a few other good posts about floats that you may find helpful.

发表在 前端技术 | 留下评论

bfc w3c文档

http://www.w3.org/TR/CSS21/visuren.html#block-formatting

发表在 前端技术 | 留下评论

On having layout

Introduction

A lot of Internet Explorer’s rendering inconsistencies can be fixed by giving an element “layout.” John Gallant and Holly Bergevin classified these inconsistencies as “dimensional bugs,” meaning that they can often be solved by applying a width or height. This leads to a question of why “layout” can change the rendering of and the relationships between elements. The question, albeit a good one, is hard to answer. In this article, the authors focus on some aspects of this complicated matter. For more thorough discussions and examples, please refer to the links provided.

hasLayout — A Definition

“Layout” is an IE/Win proprietary concept that determines how elements draw and bound their content, interact with and relate to other elements, and react on and transmit application/user events.

This quality can be irreversibly triggered by some CSS properties. Some HTML elements have “layout” by default.

Microsoft developers decided that elements should be able to acquire a “property” (in an object-oriented programming sense) they referred to ashasLayout, which is set to true when this rendering concept takes effect.

Nomenclature

We speak of an element “gaining layout” or say that an element “has layout” when the Microsoft-proprietary property hasLayout is set to true for it. A “layout element” can be any element which has layout by default or has gained layout by setting some appropriate CSS property.

In “non-layout” elements, hasLayout is not triggered, i.e. a pure div without a dimension can be a “non-layout ancestor”.

Giving or applying “layout” to an element that does not have it by default involves setting a CSS property that triggers hasLayout = true for the element in question. See Default Layout Elements and Properties for these listings. There is no way to set hasLayout = false other than to remove or reset the CSS property that caused hasLayout = true in the first place.

The Hand We’ve Been Dealt

The hasLayout problem affects designers (and coders) at all experience levels. Layout has unusual and hard to predict effects on the display of boxes, as well as implications for their descendant elements.

Consequences of an element having, or not having “layout” can include:

  • Many common IE float bugs.
  • Boxes themselves treating basic properties differently.
  • Margin collapsing between a container and its descendants.
  • Various problems with the construction of lists.
  • Differences in the positioning of background images.
  • Differences between browsers when using scripting.

The above list is brief and incomplete. This article attempts to more thoroughly describe issues encountered by the application of “layout” or the lack of it.

Where Layout Comes From

Unlike standard properties, or even proprietary CSS properties available in different browsers, layout is not directly assigned via CSS declarations. In other words, there is no “layout property.” Certain elements automatically “have layout” and it is quietly added when various CSS declarations are made.

Default layout elements

The following elements appear to have layout by default.

  • <html>, <body>
  • <table>, <tr>, <th>, <td>
  • <img>
  • <hr>
  • <input>, <button>, <select>, <textarea>, <fieldset>, <legend>
  • <iframe>, <embed>, <object>, <applet>
  • <marquee>

Properties

The following CSS property/value pairs will, if applied, allow an element to gain layout.

position: absolute
Refers to its containing block, and that’s where some problems begin.
float: left|right
The float model has a lot of quirks due to some aspects of a layout element.
display: inline-block
Sometimes a cure when the element is at inline level and needs layout. Applying layout is probably the only real effect of this property. The “inline-block behaviour” itself can be achieved in IE, but quite independently: IE/Win: inline-block and hasLayout.
width: any value other than 'auto'
This is often an implicit fix, more often the trigger when hasLayout does things wrong.
height: any value other than 'auto'
height: 1% is used in the Holly Hack.
zoom: any value other than 'normal' (MSDN)
MS proprietary, does not validate. zoom: 1 can be used for debugging.
writing-mode: tb-rl (MSDN)
MS proprietary, does not validate.

As of IE7, overflow became a layout-trigger.

overflow: hidden|scroll|auto
This property did not apply in prior versions, unless “layout” was added to the box by other triggers.
overflow-x|-y: hidden|scroll|auto
As part of the CSS3 box model module, overflow-x and -y are not widely implemented yet. They did not trigger hasLayout in prior versions of IE.

And new hasLayout actors appeared on the screen in IE7. As far as hasLayout is concerned, the min/max properties act similar to how width and height works, and the effects of fixed and absolute positioning seem to be identical.

position: fixed
./.
min-width: any value
Even the value 0 lets the element gain layout.
max-width: any value other than 'none'
./.
min-height: any value
Even the value 0 sets haslayout=true
max-height: any value other than 'none'
./.

Based on querying the IE Developer Toolbar and preliminary testing.

Notes on elements at inline level

For inline elements (either inline by default like span, or having display: inline)

  • width and height trigger hasLayout in IE 5.x and IE 6 or newer in quirks mode only. As of IE6, when the browser is in “standards-compliance mode” inline elements will ignore the width and height properties, and setting the width and height properties will not cause the element to have layout.
  • zoom always triggers hasLayout, but it’s not supported in IE5.0.

Elements having both “layout” and display: inline behave in a similar way as what the standards say about inline-block: they flow horizontally like words in a paragraph, are sensitive to vertical align, and apply a sort of shrink-wrapping to their content. As soon as the inline elements have layout, they act as inline-block, this is an explanation why, in IE/Win, inline elements can contain and hold block-level elements with less problems than in other browsers, where display: inline remains inline.

Resetting hasLayout

Resetting the following properties to their default value in a separate rule set will reset (or undo) hasLayout, if no other property giving hasLayoutremains in effect:

  • width, height (to ‘auto’)
  • max-width, max-height (to ‘none’) (in IE 7)
  • position (to ‘static’)
  • float (to ‘none’)
  • overflow (to ‘visible’) (in IE 7)
  • zoom (to ‘normal’)
  • writing-mode (from ‘tb-rl’ to ‘lr-tb’)

Authors must be careful with resetting these properties. Consider a menu system: Changing the hasLayout-status on a:hover, be it intentionally or not, might result in unexpected rendering (or IE 6 program instability when undone dynamically in combination with position: relative).

The display-property differs: while ‘inline-block’ sets haslayout = true, the flag will not be reset to false later on by overriding the value with‘block’ or ‘inline’ in another rule set.

Setting the properties min-width, min-height to their default value ‘0’ still gives hasLayout, but IE 7 accepts for them the invalid value ‘auto’, which resets hasLayout.

The hasLayout script property

We have chosen to refer to hasLayout as a “script property” in order to distinguish it from the CSS properties we are familiar with.

There is no way to set or reset the script property hasLayout directly.

The hasLayout-property can be used to check if an element has layout: If, for example, it has “eid” as id, then simply writing in the IE5.5+ address bar javascript: alert(eid.currentStyle.hasLayout) tests its state.

The IE Developer Toolbar allows for live inspecting of the current style of an element; when hasLayout is true its value is reported as “-1”. By live editing the attributes of a node, you can set “zoom (css)” to “1” to triggerhasLayout for debugging purposes.

Another thing to consider is how “layout” affects scripting. TheclientWidth/clientHeight properties always return zero for elements without “layout.” This can be confusing to new scripters and is different to how Mozilla browsers behave. We can use this fact to determine “layout” for IE5.0: If the clientWidth is zero then the element does not have layout.

CSS hacks

The following hacks to trigger haslayout have been well tested in IE7 and lower.

John Gallant and Holly Bergevin published the Holly hack in 2003:

  1. /* \*/
  2. * html .gainlayout { height: 1%; }
  3. /* */
  • Gives layout in IE5-6 to any element, except to inline elements in IE6 standards mode.
  • Works generally well, except in rare cases where height:0 or 1px is more stable.
  • Is incompatible with overflow: hidden, except in IE6 standards mode (where height: 1% reverts to height: auto, unless the parent has a specified height.)
  • Has no effect in IE7 standards mode where * html doesn’t select anything.

To give layout to IE6 and lower we can also use the underscore hack:

  1. .gainlayout { _height: 0; }

And to give layout to IE7 we can use the min-height property:

  1. .gainlayout { min-height: 0; }

Alternatively, and possibly more future proof, are conditional comments:

  1. <!--[if lte IE 6]>
  2. <style>
  3. .gainlayout { height: 1px; }
  4. </style>
  5. <![endif]-->
  1. <!--[if IE 7]>
  2. <style>
  3. .gainlayout { zoom: 1; }
  4. </style>
  5. <![endif]-->

The use of an external style sheet for whatever fixes IE-Win needs, linked from inside a conditional comment, is also a secure and elegant solution:

  1. <link rel="stylesheet" href="allbrowsers.css" type="text/css" />
  2. <!--[if lte IE 7]>
  3. <link rel="stylesheet" href="iefix.css" type="text/css" />
  4. <![endif]-->

For IE6 and lower height should “always” be used (if we want to include IE5.0 there aren’t many alternatives), unless it conflicts with something else (overflow: hidden). About the value, 1%, 1px, 0 are more or less equivalent, but 1% may (albeit very rarely) cause problems.

height cannot be used for inline elements in standard mode, and should be avoided in IE7 (or used with care: only percentage values, and then only if the parent element has no specified height). In those cases we prefer display: inline-block or zoom: 1.

We’ve seen desperate attempts of “holy” hacks (sic!) applied to floated elements, or to elements already having a width. Remember the goal of such an hack is not to apply a height to an element, but to trigger hasLayout = True.

Don’t give layout to all: * {_height: 1px;}. Poison in that concentration, having layout is not the cure, it changes the rendering fundamentally.

Hack management

As the release of IE7 has demonstrated, it’s impossible to foresee if future versions of IE will still need hasLayout to fix some bugs and how they will react to filters in use today. In this light, the use of the MS proprietary zoomand/or conditional comments, can be advised.

  1. <!--[if lt IE 7]><style>
  2. /* style for IE6 + IE5.5 + IE5.0 */
  3. .gainlayout { height: 0; }
  4. </style><![endif]-->
  5. <!--[if IE 7]><style>
  6. .gainlayout { zoom: 1; }
  7. </style><![endif]-->
  • zoom: 1; gives layout in IE5.5+ to any element (including inline elements), but it has no effect in IE5.0
  • No known side effects (inline elements behave like inline-block, though).
  • If validation is required, zoom must be hidden via conditional comments.

While we think “future proof” is a contradiction in terms, we strongly suggest the web designer “plays for sure” and review her pages for explicit and implicit “hacks” and use conditional comments to serve those hacks to the appropriate browser version.

For a more detailed overview of hasLayout triggers and comparison of hasLayout hacks in the various IE versions, see Thoughts on IE hack management.

A short note about IE Mac.

IE Mac and IE for Windows are two different animals, living in separate parts of the zoo. Each has its own rendering engine, and IE Mac doesn’t know about the “hasLayout” behaviour (or contenteditable) in any way. The IE Mac rendering engine tend to be rather standard compliant, with i.e. height being treated asheight, as it should. Hacks and workarounds for the “hasLayout” problems (especially when using the height or width properties) will often have rather detrimental effects on IE Mac, and should be hidden from that browser. More on IE Mac problems can be found at the IE Mac, bugs and oddities pages.

MSDN documentation

In the MSDN, there are very few pages related to the hasLayout MS-property, and less is explained how having layout correlates with the visual formatting model of IE.

Back in IE4, nearly every element had sort of layout, except for simple inline elements not positioned absolutely and without a dimension (MSDN – document was modified1). And in this early layout concept, there were “layout properties” like border, margin, padding, which can’t be applied to such a simple inline element. In other words, “having layout” was just another term for roughly: “may have these properties.”

MSDN still speaks of “layout properties,” but the meaning has changed, they are not associated with elements having layout anymore. In IE5.5, the MS-propertyhasLayout was introduced, more or less an internal flag.

In IE5.5, the documentation of the MSHTML Editing Platform (which allows for live editing, sizing, and dragging layout elements via <body contenteditable=true>) reveals three important aspects related to having layout:

If a layout element has contents, the layout of its contents is determined by its bounding rectangle.

Having layout basically means an element is rectangular.

Internally, having layout means that an element is responsible for drawing its own content.

(Editing Platform — document removed from the MSDN2)

The inner workings related to layout itself was not documented until August 2005, when, as a result of The Web Standards Project and Microsoft task force, Markus Mielke [MSFT] opened the door for a thorough discussion:

In general, elements in Internet Explorer’s Dynamic HTML engine are not responsible for arranging themselves. A div or a p element may have a position within the source-order and flow of the document, but their contents are arranged by their nearest ancestor with a layout (frequently body). These elements rely on the ancestor layout to do all the heavy lifting of determining size and measurement information for them.

(HasLayout Overview)

Interpretation

Our interpretation is an attempt to explain what happens in known cases, and it should serve as a guide for cases not fully known. The attempt to demystify a black box only by inserting some test cases into it and listen if it rattles is doomed to failure. The “question why” cannot be answered. We have to try to understand the framework in which the whole “hasLayout” model works, and how it affects rendering of web documents. Out of this, guidelines can be developed (and those can only be guidelines, not absolute solutions).

We think they speak of a little window. The content of a layout element would be completely independent from anything outside of the element’s boundary, and the content couldn’t affect anything outside either.

The hasLayout MS-property is a sort of flag: when it is set, the element has this layout “quality”, which includes special capabilities — for instance, on the floating and stacking — for the element itself and for its non-layouted child elements.

This greater independence of layout elements is probably the reason why they are usually more stable, and so they make some bugs to disappear. The price for this can be both deviance from standards, and further bugs/problems at their boundaries.

The MS “page” model, thinking in semiotics, can be seen as consisting of little blocks of stories that are unrelated, where as the HTML and W3C model has “page” model as complete narrative, story, blocks of information that are related.

A review of the consequences

Clearing floats and the extend to fit

Floats are auto-contained by layout elements. That’s one reason why most beginners struggle with their IE-build pages in a compliant browser where floats stick out of the container when not cleared.

The opposite behavior: what if a float must stick out of its container, e.g. when auto-containing is not the desired effect? For a demonstration of the frustrating problems one might encounter, check out our in-depth discussion:

In IE, a float will always “belong” to its layout container. Subsequent elements might respect the layout container, but not the float itself.

This, and IE6’s expanding of a container to fit any wider content (the “extend-to-fit”), can be seen as an aspect of the “determined by its bounding rectangle” rule.

Even worse: clear can’t affect a float outside of the clearer’s layout container. Float layouts relying on that bug in IE cannot be transferred to work in a compliant browser without a general re-do.

The IE’s auto-containing of float, which is sometimes unavoidable, can be achieved in other browsers: see our section “Similarities with the CSS specs” for concepts on containing floats.

Elements next to floats

When a block follows a floated element, it should — as a block — ignore the float, but its contents should be displaced by the float: the text in a block-level element next to a left-floated element should flow to the right of the float, and then (if it is longer than the float) continue below the floated element. But if the block has “layout”, say, a width is set for some reasons, then the whole element is displaced by the float, as if it were a float itself, and so the text content does not wrap around the float anymore (it remains at its right, rectangularly shaped.)

A percentage width for the block is computed in IE 5 on the basis of the available space at the side of the float, and in IE 6 on the basis of the full available width of a parent block. So in IE 6 a width: 100% results in something not fitting at the side of the float, with all the layout problems that not-fitting blocks may cause.

Test cases for hasLayout blocks adjacent to floated blocks:

Similar to this, actually, relatively positioned elements next to floats should offset with respect to the padding edge of the parent (i.e. left: 0; on a r.p. element would place it on top of a preceding left floated box). In IE 6, the offset left: value; starts from the right margin edge of the float, causing a horizontal misalignment by the total outer width of the float (a workaround is to use margin-left instead, but beware the quirky percentages flaws).

According to the specs, floats interweave with subsequent boxes. This cannot be accomplished with two-dimensional rectangles that don’t intersect.

If the author gives in to IE’s inadequacy, then the question arises how to get boxes in standards compliant browsers look similar to these layout boxes which “retract” to make room for a preceding float. We’re giving options to establish a new block formatting context next to the float in our section “Similarities with the CSS specs”.

By (re-)visiting this bug page in IE 6

we’ll see that the layout box following the float will not show the 3px text jog, because the float’s hardwired 3px surrounding cannot affect the content inside the layout element anymore, but moves the whole layout element by 3px. Like a shield, layout prevented the content from being affected, but the energy of the push by the float moves the shielded box itself.

Lists

Lists are affected by layout applied either to the list (ol, ul) or to the list elements (li). Different versions of IE react differently. The most evident effects are on the list markers (fully customized lists where the markers are not required won’t have these problems.) The markers are probably created by internally adding some elements that are somewhat “attached” to the list elements (usually hangs out of them) and seems rather unstable. Unfortunately, being “internal” only objects, they cannot be accessed to try to correct mis-behaviours.

The most evident effects are:

  • Layout applied to a list makes the markers to disappear or to be differently/wrongly positioned.

Sometimes they can be restored by changing margins on the list elements. This looks like a consequence of the fact that a layout element tends to crop internal elements hanging out of it.

A further problem is that (in ordered lists) any list element with layout seems to have its own counter. Let’s say we have an ordered list with five elements where only the third has layout. We’ll see this:

1… 2… 1… 4… 5…

Moreover when a list element with layout displays on multiple lines the marker is vertically aligned at the bottom (not at the top, as expected.)

Some of these problems cannot be cured, so when the markers are desired it’s better to avoid layout on lists and list elements. If it’s necessary to apply some dimension, this is better applied to other elements: for example a width can be applied to an external wrapper, and a height to the content of each list item.

Another common problem with lists in IE occurs when the content of anyli is an anchor with display: block. In these conditions the white space between list items is not ignored and usually displayed as an extra line for each li. One of the methods to avoid this extra vertical space is to give layout to the block anchors. This also has the benefit of making the whole rectangular area of the anchors clickable.

Tables

A table always has layout, always behaves as a width defined object. In IE6, table-layout: fixed is usually equivalent to a table with a width of 100%, with all problems that this brings (erroneous computations). As a side note, just a few things on the situation in IE5.5 and “quirks mode” IE6.

Relatively positioned elements

Note that position: relative does not trigger hasLayout, which leads to some rendering errors, mostly disappearing or misplaced content. Inconsistencies might be encountered by page reload, window sizing and scrolling, selecting. With this property, IE offsets the element, but seems to forget to send a “redraw” to its layout child elements (as a layout element would have sent correctly in the signal chain of redraw events).

are related descriptions. As a rule of thumb, never position an element relatively without setting layout. In addition, we may check if the parent of such a construct needs layout and/or position: relative too, this becomes essential when floats are affected.

Absolutely positioned elements:
Containing block, what containing block?

It is essential to understand the CSS concept of the containing block, which answers where to relate an absolutely positioned (a.p.) element to: to define the offset origin, and to define the length percentages are calculated with respect to.

For a.p. elements, the containing block is established by its nearest positioned ancestor. If there is no such ancestor, the initial containing block of html is used.

Normally, we would set such a containing block via position: relative. That means, we can let a.p. elements relate to lengths and origins independent from the flow of elements, i.e. to fulfill the needs of the “content first” accessibility concept or to make life easier in complex float layouts.

This design concept is questioned by IE: offsets of an a.p. element are correctly computed only if the containing block has layout, and a percentage width of an a.p. element may refer to the wrong ancestor. Here IE 5 and IE 6 behave differently, but both have problems. IE 7b2 has a more consistent behaviour, but is still incorrect in some cases. When possible, try to stick to cases where the containing block has layout and it is the parent of the a.p. element (i.e. there aren’t other ancestors in between the a.p. and the containing block).

Say a non–layout parent is positioned relatively — we are urged to set layout to this parent to get the offset to work:

Say a non-positioned parent must have a dimension, and the design relies on a percentage width calculation — we can drop that idea, due to a lack of browser support:

Filter

The MS-proprietary filters are applicable to layout elements only. They show their own specific flaws.

Re–flow of rendered elements

Once all the elements are rendered, IE reflows the containing layout block when a :hover-transition (i.e., a change of the link’s background) occurs. Sometimes the elements are placed at a new position because at the moment the hover occurs, all the widths and offsets of the related elements are known to IE. This is unlike to happen on first load, where the width is undetermined yet due to the expand-to-fit feature. This can result in a jump on hover.

These relational bugs, based on the re-flow problem, create problems in liquid layouts where is most common the use of percentages for margins and paddings.

Background origin

The hasLayout MS-property affects the extension and the positioning of the background. For example, according to the CSS spec, background-position: 0 0 should refer to the “padding edge” of the element. In IE/Win it refers to the “border edge” when hasLayout = false, and to the “padding edge” when hasLayout=true:

Margin collapsing

The hasLayout MS-property affects the collapsing of margins between a box and its descendants. According to the spec the top margin of a box with no top padding and no top border should collapse with the top margin of its first in-flow block-level child:

In IE/Win this never happens when the box has layout: it seems that layout prevents the margins of the children to stick out of the containing box. Moreover when hasLayout is true, either on the container or on the child, other wrong margins computations show up:

Horizontal margins get copied onto form elements

Form elements whose immediate containing box has layout, inherit the sum of the horizontal margins of all of their containing boxes, up to, but not including, the next containing box having layout.

A fix, for most cases, is to give layout to the containing box next to the immediate one. Another fix, one that works for all cases we have found, is to add an innermost, unstyled, container around the form element.

hasLayout affects the clickable/hoverable area of a block-level anchor. Usually with hasLayout = false only the part covered by the text is sensitive. With hasLayout = true the whole block area is sensitive. The same is true for any block element with an attached onclick/onmouseover event handler.

In–page keyboard navigation: an odyssey

While tabbing through a page and entering an in-page link, the next tabkey press won’t resume on the subsequent anchor:

The tab will bring — and often mislead — the user to the first target of the nearest layout ancestor (if this layout ancestor is formed by a table, div,span and certain other elements).

Shrink-wrapping

Some properties applied to elements with width: auto cause them to compute their width with a shrink-wrap algorithm. Examples of such properties are float: left|right, position: absolute|fixed, display: table|table-cell|inline-block|inline-table.

This works in IE/Win, of course limited to the supported properties. But when the element which should shrink-wrap contains a block element with “layout” assigned, then in most cases this child expands to the full available width, independently of its content, and prevents the shrink-wrapping effect of the parent.

Example:
A floating vertical navigation ul fails to shrink-wrap, because for the links, a {display: block; zoom: 1;} was needed to fix the list whitespace bug and to expand the clickable area.

The shrink-wrap remains in effect only if the layout child has an assigned width, or it has a shrink-wrap property itself, such as float.

Clipping over the edge

In general, when a box contains more complex structures like protruding content, “hasLayout” on this container is often necessary to avoid rendering problems. This almost-requirement causes a dilemma at the boundaries, since a block element that gains “layout” becomes a sort of self-enclosed box.

Nested content boxes that are moved outwards from that element (by using negative margins, for example) are clipped.

The clipped portions can be restored by triggering “hasLayout” on that content box, and position: relative is also needed in IE 6. The IE 7 behaviour seems slightly better in that position: relative is no longer necessary.

The stack, the layering, and layout

There seem to be two layering and stacking orders within IE/Win:

  • One is the (pseudo) attempt to implement the css model: Effect of z-index value to RP and AP blocks
  • Then there is the stacking order created by “hasLayout” and its twin the “contenteditable” behaviour. As shown in the example to relative positioning, not having layout can affect the stacking in a way Harry Houdini would had have fun with.

Both stacking models, though incompatible, are residents of IE’s engine. As a rule of thumb: While debugging, don’t miss checking both suspects. We regularly see related problems in drop down or similar complex menus, where the stacking, positioning and floating can lead to manifold disasters, and bug fixes may include giving z-indexed positioned layout, but it varies, so be warned.

The contenteditable–debacle

The attribute contenteditable=true, set on a HTML tag like <body contenteditable=true> allows for live editing, dragging and re-sizing the element and it’s layout children. Now try that with floats or layout li in an ordered list.

In order to manipulate elements (edit them), “contenteditable” and “hasLayout” introduce a separate stacking order for those elements which return true forhasLayout.

The Editing Platform (document removed from the MSDN2) inherits the layout-concept, evidence can be seen that contenteditable is the reason for the layout-misconception (with the implication that applications that somewhat integrate the IE editing engine force a backward compatibility to this layout-concept).

Similarities with the CSS specs

Are your MSIE-designed pages failing in other browsers? No need to let that happen, you know! Any good browser can handle MSIE-designs just fine if you ask them nicely — and serve them some valid CSS.

Utilizing the slight similarities found between hasLayout and the establishment of “new block formatting context” gives us some means to reproduce the effects of hasLayout for “containment of floats” and for the behaviour of “elements next to a floated element” in standard compliant browsers.

Quirks mode

Please refer to our quirks mode chapter for information about this rendering mode.

Layout — a conclusion

The layout concept as a whole is not compatible to a number of basic CSS concepts of the visual formatting model, namely containing, the flow, floating, positioning and layering.

This leads to IE/Win specific violations of the CSS specification due to the presence or absence of layout on elements in the page.

Having layout — part of another engine?

The object model inside Explorer appears to be a hybrid of a document model and their traditional application model. I mention this as it is important in understanding how Explorer renders pages. The switch for jumping from a document model to an application model is to give an element “layout”.

(Dean Edwards)

Sometimes it’s impossible to give an interpretation to some behaviour: it’s simply like, depending on hasLayout status, one of two different rendering engines is used, each one with its own quirks and bugs.

The absurdity of bugs

Software-bugs are the result of human errors and lack of completeness and logic during the creation-process. It’s a fundamental human shortcoming, for which a lasting cure is yet to be found.
Any attempts to correct buggy software without recreating it from scratch, will inevitably lead to even more and more complex bugs finding their way into the software, because of the same human shortcomings.
All software that rely on other software — including Operating Systems (of course), will also rely on its bugs. Thus we get a cascade of bugs from all involved bits of software, which makes even the thought of finding bug-free software completely absurd.

(Molly ‚the cat‛)

This article was created on June 30, 2005 and last changed on November 16, 2008.

Editors:
Holly Bergevin
Ingo Chao, coauthor of “Fortgeschrittene CSS-Techniken inkl. CSS-Debugging
Bruno Fassino
John Gallant
Georg Sørtun
Philippe Wittenbergh
Special thanks for supporting the project to:
Dean Edwards, Molly ‚the cat‛, David Laakso and Corina Rudel
Translations:
Brazilian Portuguese by Mauricio Samy Silva, author of “Construindo Sites com CSS e (X)HTML
Bulgarian by Yordan Stoev
Chinese by old9
French by Jean-Jacques Solari
German by Corina Rudel
Italian by Gabriele Romanato
Russian by DreamwinD
Translations are welcome, please get in touch with us.
Discuss this article:
dean.edwards.name/weblog/
Contact us:
Copyright notice:
This work is published under a Creative Commons license.

Table of contents

  1. Introduction
  2. hasLayout — A Definition
  3. Nomenclature
  4. The Hand We’ve Been Dealt
  5. Where Layout Comes From
  6. Default layout elements
  7. Properties
  8. Notes on elements at inline level
  9. Resetting hasLayout
  10. The hasLayout script property
  11. CSS hacks
  12. Hack management
  13. A short note about IE Mac.
  14. MSDN documentation
  15. Interpretation
  16. A review of the consequences
  17. Clearing floats and the extend to fit
  18. Elements next to floats
  19. Lists
  20. Tables
  21. Relatively positioned elements
  22. Absolutely positioned elements: Containing block, what containing block?
  23. Filter
  24. Re–flow of rendered elements
  25. Background origin
  26. Margin collapsing
  27. Horizontal margins get copied onto form elements
  28. Block–level links
  29. In–page keyboard navigation: an odyssey
  30. Shrink-wrapping
  31. Clipping over the edge
  32. The stack, the layering, and layout
  33. The contenteditable–debacle
  34. Similarities with the CSS specs
  35. Quirks mode
  36. Layout — a conclusion
  37. Having layout — part of another engine?
  38. The absurdity of bugs
  1. The original document has been modified in the MSDN. We are referring to a version that is available in the Internet Archive (Controlling Presentation with Measurement and Location Properties).
  2. The original document has been removed from the MSDN and is available in the Internet Archive (The MSHTML Editing Platform in Internet Explorer 5.5).
发表在 前端技术 | 留下评论