Ссылки о веб-разработке за октябрь 2011

godaddy не для русских

когда я разбирался с этой проблемой, на одном из форумов я прочитал приблизительно такие слова: «ну это же godaddy, не может быть, чтобы у них это не работало». Так вот, у них это действительно не работает уже много лет. Сейчас расскажу, что.

первые стандарты на почту не предполагали, что в заголовках письма будут не-ascii символы. Потом стандарты доработали, и их стало можно туда включать, обычно в base64-кодировке. Но из-за этой кодировки с обёртками длина заголовков увеличивается и нередко вылезает за разрешённые 75 символов. Впрочем, это не проблема: заголовки можно переносить на следующую строку. Вот так:

Subject: Re:

вернее, нельзя. На GoDaddy нельзя. Такой у них php. Заголовок с темой не должен содержать переносов строки. Они про это знают, но ничего делать не собираются, потому что боятся что-нибудь сломать. Поэтому если вы хотите с этой площадки слать посредством php письма на русском, делайте заголовки короче 25 символов. Ну или найдите нормальный хостинг.

есть, конечно, вариант не переносить строку, но это нарушает стандарт, и чёрт его знает, кому от этого перестанет приходить почта.

What’s slated for CSS4 Selectors?

The CSS Working Group recently published the first working draft of CSS4 Selectors. “Wait…CSS 4? I thought CSS3 was still incomplete” you might ask. The spec process changed after CSS2.1. Instead of one monolithic spec, CSS3 was broken down into smaller bite sized chunks. Each chunk or module graduate to the Recommendation stage independently when they’re ready. As each module doesn’t depend on each other (typically. Some related modules might have dependancies, such as CSS3 Selectors on CSS Namespaces) work can start on the next level of the module–if there is demand for a new version–after the current level reaches REC. Therefor work on CSS4 specs will go on in parallel with CSS3 modules. The selectors specification is one such module where there is demand for some new features .

Introducing Selectors level 4

The CSS4 Selectors spec has already seen a large number of revisions since level 3. As it is still the first draft of the spec, it will likely change in numerous ways before it becomes a recommendation itself and there are browser implementations. Lets have a quick dig into the draft and see what has changed.

Moving homes. In-N-Out the spec

There are some selectors that were moved into CSS4 Selectors from other specs, and some that were removed and are looking for a new home:


One of the first things you may notice about the spec is that pseudo-elements are gone from the spec. Don’t worry though, they will find a new home in a different spec in the future. I’m not sure if this will be its own spec or merged into another one. I wonder if this is to prepare for styling the Shadow DOM.

UI state pseudo-classes

While pseudo-elements were moved out, the user interface state pseudo-classes from CSS3 Basic User Interface have been moved into the spec. These target various states that UI components can be in, such as if checkbox is checked or unchecked or if a value is required or not. They were mapped to XForms states in CSS3 UI, but they are in general language agnostic. They’re perfect for styling HTML5 Form elements. I assume they were moved to put all the selectors in one place except pseudo-elements. Makes sense to me.

Contextual reference element pseudo-class

What a mouthful. This is the :scope pseudo-class. You might not have heard of this, but it comes from Selectors API Level 2.

If you don’t understand what the :scope pseudo-class does then don’t worry. It is quite difficult to understand from the spec, and I had to ask the Lachlan Hunt myself. As far as I understand it, the :scope pseudo-class acts as a placeholder in the selector list. It is replaced by a specified reference element. In the case of Selectors API 2, the element can be specified as an argument in the querySelector, querySelectorAll and matchesSelector methods. This is much easier to understand if I show it in an example:

    var el = document.querySelector("#foo"); // returns first element with ID of foo
    var bar = document.querySelector(":scope > p", el); // returns equivalent of "#foo > p"

In the above example, “:scope > p” and “#foo > p” are not 100% equivalent. The later will return the first p element that is a child of an element with ID of “foo”. With the former, instead of any #foo, it will only use the first #foo in the document. As multiple IDs are illegal the difference in this particular example will not show off too often, but as you can imagine, the difference is important when using a reference element can appear multiple times in the document.

The :scope selector is most useful when reference elements are generated programatically, so it is not possible to write a static selector string. The selector is not currently implemented in any browser.

Changes to existing selectors

In CSS3 selectors, the negation selector (:not) can only accept a simple selector. A simple selector is either a type selector (an element name such as p or em), universal selector (the selector), attribute selector (those that target attributes such as [att], [att=val], etc.), class selector, ID selector, or a pseudo-class selector. Pseudo-elements and combinators (e.g. ul li, ul >li etc.) are not supported, and the negation selector can not be nested. These restrictions have been relaxed somewhat in CSS4 Selectors to also allow a selector list. Both simple and compound selectors are allowed. Pseudo-elements and nested selectors are still not supported however.

New proposals

There are quite a few new selectors that have been proposed in the new spec, including one that has been much demanded by web developers.

Matches-Any Pseudo-class

The :matches() pseudo-class is the standardised version of Mozilla’s :-moz-any() pseudo class. This is useful for when you need a number of similar selector strings, but change one part such as the pseudo-classes. Instead of writing li a:link, li a:hover, li a:visited, li a:focus, you can write li a:matches(:link, :hover, :visited). Only simple or compound selectors are allowed. Complex selectors, nesting and using within :not()is forbidden.

Directionality pseudo-class

The dir() pseudo-class selects elements depending on its directionality. This is commonly the direction of any potential text in the element, set with the HTML dir attribute. Note that the dir attribute does not need to be set directly on the element. It could be inherited from its parent. It does not match based on the CSS direction property.

The currently defined values are rtl (right to left, e.g. used with Hebrew or Arabic text) and ltr (left to right, e.g. used with latin text). Other values are not invalid, but are not defined to do anything. This allows the spec to be extended if new values are needed (top to bottom for example?).

Hyperlink pseudo-class

The any-link() pseudo-class matches links, no matter if their history state is unvisited (:link) or visited. This is needed because once a link is visited the regular :link pseudo-claass does not apply any longer. This saves you having to specify both when you want to style both states the same way. The name is not set in stone, so if you have a better suggestion then get in touch with the working group.

Local link pseudo-class

The :local-link pseudo-class selects elements whose links are local links. If you use the plain :local-link pseudo-class, without parenthesis, then it matches elements that link to the current page. That is exactly the same URL as the document, sans any fragment identifier. Parenthesis can be added, taking a digit as a value. Using 0 (a:local-link(0)) will match a link that is the same domain. A value of 1 matches the domain and the first path segment. A value of 2 matches the domain and the first two path segments, and so on. For example, if the URL of the document is http://www.example.com/foo/bar/baz, the a:local-link(1) would match a elements with links that matches http://www.example.com/foo, while a:local-link(2) would match a elements with links that matches http://www.example.com/foo/bar.

Time-dimensional pseudo-classes

There are three time-dimensional pseudo-classes: :past, :current, and :future. These relate to time related rendering (or time-dimensional canvas as the spec says), such as speech rendering of HTML documents (text to speech). The :current pseudo-class matches the element that is currently being rendered (such as styling the image that is currently being spoken). The :past pseudo-class styles matches elements that were rendered in the past (e.g have already been spoken), and :future matches elements that will be rendered in the future (will be spoken). There is also a version of :current that takes arguments in parenthesis. This works in much the same way as the :matches() pseudo-class, where it matches any of the comma separated selector compound selector strings. I am not 100% if I got this one right, as I am not familiar enough with time-dimensional canvas.

New tree-structural pseudo-classes

There are two new tree-structual pseudo-classes: nth-match and nth-last-match. These work much the same way as nth-child and nth-last-child, using the same an+b notation. However you also include the of keyword and a selector string that is used to match a subset of the results. This is difficult to understand when reading the spec, but an example makes it clearer. If you have the selector button:nth-match(even of .active), instead of selecting all even button elements as with button:nth-child(even), it will first match the subset of elements with a class of active, then match the even elements from that subset.

Grid-structure pseudo-classes

There are three grid-structure pseudo-classes: :column(), :nth-column(), and :nth-last-column. In HTML individual cells of tables are marked up in rows (using the tr element). The column the cell belongs to is implied rather than than the cell being a child of the col element. Due to this one dimensional hierarchy, to style individual table cells based on the column it belongs to, we need the :column() selector. It accepts a list of one or more selectors. Based on the semantics of the language, it calculates if the cells belong in the columns that match the selector list. For example :column(col.total) selects all the td cells in the total column.

The nth-column() and nth-last-column accept an+b notation as their argument, in the same way as other similar pseudo-classes. For example, :nth-column(odd) would select all table cells in odd columns.

Reference combinators

Reference combinators allow you to select elements that are referenced by ID by another element. One of the most common occurrences of this is when a label references the ID of its related control in the for attribute. You define a reference combinator by surrounding the attribute with forward slashes (/). For example, if you wanted to style an input element when you hover over its label, you could use the selector label:hover /for/ input (providing the label has a for attribute with the correct ID).

The mythical unicorn: parent selector

That most demanded of selectors is now in the spec. Well not quite. It isn’t just a parent selector. You can now select which element is the subject of the selector. Traditionally this is the right most compound selector in the selector string. This is currently defined with the dollar sign ($), but there is currently some debate on the mailing list, and will likely change. The compound selector that is marked as the subject is the one that will be styled by the CSS rule. If you have a selector such as ul li.selected, it will match an element that is of type li that is a decedent of a ul element. However, if you want to only style a ul if one of its li elements has a class of selected, you need to make the ul the subject of the selector like so: $ul li.selected. Now all your prayed are answered!

This is the current state of play with the first CSS4 Selectors draft. Anything can and will change as the spec progresses. There are very little in the way of implementations of these features, so I can’t check if I understood them all 100% correctly. If I didn’t then let me know and I’ll update the post.

простреленная нога по-берлински

у наших разработчиков есть интересная особенность оформления кода внутри модуля. Если им нужно объявить функцию внутри замыкания, они не идут простым путём, и не пишут что-то вроде

function a() {
    // …

нет, объявление функции не для них. Вместо этого они объявляют переменную в var и присваивают ей значение, вот так:

var a = function() {
    // …

особенно смешно это сочетается с попытками использовать JSLint, который ругается на попытки использовать не только функции, но и переменные до их объявления.

но это ещё не всё! Одна из команд, видимо по привычке, использует этот стиль, но не использует JSLint. Конечно же, когда перед тобой несколько экранов кода, легко забыть, что это всё ещё «объявление переменных», и поставить точку с запятой в конце строки. Или не поставить, тут это без разницы:

var a = 123,
    b = function(){};
    c = b(a),
    d = c + 1;

в обоих случаях эта строчка станет последней строчкой var, и все объявленные позже переменные утекут в глобальную область имён. Гип-гип-ура!

за несколько месяцев я раз десять обнаруживал и чинил такие вот «протечки». А когда на этот код всё-таки напустили JSLint, он нашёл только забытый кем-то debugger;. Вот и получилось, что для нас JSLint создал больше проблем, чем решил

вообще, по-моему, это очень иронично: JSLint заявляет своей целью отказ от «опасных» подходов написания кода, но сам в то же время заставляет использовать другой опасный подход

inline SVG: data URI

open google reader я разрабатывал в том числе для того, чтобы использовать его на мобильных устройствах. Экранчики там маленькие, поэтому на кнопках лучше рисовать символы, а не писать названия. К сожалению, на обеих моих нокиях нет возможности использовать многие символы Unicode, поэтому мой любимый способ вставки иконок для них не подходит.

но я не унывал: на дворе 2011 год, торжество веб-технологий, поэтому сейчас я быстро что-нибудь изображу на SVG! Ведь ещё в 2007 году я вставлял его в веб-страничку для презентации на ClientSide. Да не тут-то было: я оказался в локальном минимуме технологий между двумя пиками.

дело в том, что inline SVG прекрасно вставляется в XHTML — спасибо XML и его namespaces. Не менее прекрасно он вставляется в HTML5-странички. Однако мой частный случай не даёт мне ни одной из этих возможностей: страницы гугла — не XHTML, и юзерскрипту этого не изменить, а мобильная опера ещё не содержит HTML5-парсера, поэтому не показывает SVG в обычном HTML.

и тут я вспомнил про старшенького недалёкого братца inline SVG: вставку картинок и прочих объектов посредством data: URI. Недалёким я его считаю потому, что он использует base64, а этот формат бинарный в том смысле, что невооружённым глазом его фиг прочитаешь. Впрочем, кто сказал, что base64 обязателен? В конце концов, эта кодировка прямо указывается в URI, так что можно попробовать её и не указывать.

долго ли, коротко ли, путь ошибок привёл меня к истине: раз это называется URI, оно должно выглядеть, как URI. То есть, всяких там пробелов, угловых скобок, двоеточий и кавычек содержать не должно. Поэтому совсем красивый код SVG таким образом в страницу не вставишь. Однако некрасивый — вставишь. Имена тегов, имена и значения атрибутов остаются почти прежними, а это для меня гораздо лучше base64.

впрочем, честно говоря, я не смог отказать себе в красоте. Раз уж я делаю веб-приложение, без яваскрипта вообще ни на что не годное, то encodeURIComponent — мой друг (и не нужно работать с битами на яваскрипте). А ещё один мой друг — The Noun Project. Там можно взять «путь» для svg-картинки и вставить его в нужную обёртку. Вот так:

'<img src="data:image/svg+xml,' +
    encodeURIComponent(svg.replace('{path}', path)) + '">'

а теперь картинки! Вот для начала пример счастливого будущего нормального inline SVG:

а вот как его можно вставить при помощи data URI:

Каскадные Таблицы Стилей / CSS Shaders: 3D-эффекты для веба

Компании Adobe, Apple и Opera совместно разработали спецификации CSS Shaders для генерации качественных видеоэффектов в браузере, причём фильтры можно накладывать на любой HTML-элемент. Они выглядят знакомо для всех, кто применял эффекты в редакторе Flash-анимации, или для тех, кто знает элемент filter из стандарта Filter Effects 1.0 для SVG. Здесь то же самое, только гораздо лучше.

read more…

← предыдущий месяц