Введение в веб-компоненты. Часть 1

http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html
  • Перевод
От переводчика: Представляю вашему вниманию перевод многообещающего стандарта Веб-компонентов от Google, который может стать трендом в ближайшие несколько лет. В данный момент, знание этого стандарта не несёт практического применения, поэтому, если вы не фанат всего нового и интересного, вам возможно будет скучно читать данный перевод.
Перевод выложен на github, поэтому, если вы хотите помочь с переводом или исправить ошибку сделайте pull request, ну или пишите в личку.

Статус: Эксперементальный драфт

Авторы:


Введение



Компонентная модель для Web'а (или Web Components) состоит из четырёх модулей, которые, будучи использованными вместе, позволят разработчикам web-приложений создавать виджеты с богатыми визуальными возможностями, легкие в разработке и повторном использовании, что в данный момент невозможно с использованием только CSS и JS-библиотек.


Модули:

  • шаблоны (templates), определяюют часть неактивной разметки, которая может быть использована в дальнейшем;
  • декораторы (decorators), позволяют с помощью CSS управлять визуальными и поведенческими изменениями в шаблонах;
  • пользовательские элементы (custom elements), позволяют авторам определить их собственные элементы (включая представление и API этих элементов), которые могут быть использованы в основном HTML-документе;
  • скрытый DOM (shadow DOM), определяет, как представление и поведение декораторов и пользовательские элементы сочетаются друг с другом в дереве DOM.


Вместе декораторы и пользовательские элементы называются компонентами

Шаблоны



Элемент <template> содержит разметку, предназначенную для использования позже с помощью скрипта или другого модуля, который может использовать шаблон (например, <decorator> и <element>, которые описаны ниже).

Содержимое элемента <template> анализируется парсером, но оно неактивно: скрипты не запускаются, изображения не загружаются и т. д. <template> Элемент не выводится.

В скрипте такой элемент имеет специальное свойство content, которое содержит статическую DOM-структуру определённую в шаблоне.

Например, разработчику может понадобиться определить DOM-структуру, которая создается несколько раз в документе, а затем создать его экземпляр, когда это будет необходимо.

<template id="commentTemplate">
    <div>
        <img src="">
        <div class="comment"></div>
        …
    </div>
</template>

var t = document.querySelector("#commentTemplate");
// Заполнить содержание и значения img[src] в шаблоне.
// …
someElement.appendChild(t.content.cloneNode());


Добавление статического DOM-узла в документ делает его «живым», как если бы этот DOM-узел был получен через свойство innerHTML.

Декораторы



Декоратор это нечто, что улучшает или переопределяет представление существующего элемента. Как и все аспекты представлений, поведение декораторов контролируется с помощью CSS. Однако, возможность определять дополнительные аспекты представления, используя разметку — уникальная черта декораторов.

Элемент <decorator> содержит элемент <template>, который определяет разметку используемую для рендеринга декоратора.

<decorator id="fade-to-white">
    <template>
        <div style="position: relative;">
            <style scoped>
                #fog {
                    position: absolute;
                    left: 0;
                    bottom: 0;
                    right: 0;
                    height: 5em;
                    background: linear-gradient(
                    bottom, white 0, rgba(255, 255, 255, 0) 100);
                }
            </style>
            <content></content>
            <div id="fog"></div>
        </div>
    </template>
</decorator>


Элемент <content> указывает на место, куда декоратор (точнее, его содержимое) должен быть вставлен.

Декоратор применяется, используя CSS-свойство decorator:

.poem {
    decorator: url(#fade-to-white);
    font-variant: small-caps;
}


Декоратор и CSS описанные выше заставят данную разметку:

<div class="poem">
    Two roads diverged in a yellow wood,<br>
    …
</div>

+Но её рендер будет как у этой разметки (стили user agent опущены для краткости):

<div class="poem" style="font-variant: small-caps;">
    <div style="position: relative;">
        Two roads diverged in a yellow wood,<br>
        …
        <div style="position: absolute; left: 0; …"></div>
    </div>
</div>

Если документ изменился так, что CSS-селектор, где был объявлен декоратор, более не действителен — обычно, когда селектор со свойством decorator более не применяется к элементу или правило с декоратором было изменено в атрибуте style, декоратор более не применяется, возвращая рендеринг элемента в первоначальное состояние..

Даже несмотря на то, что CSS-свойство decorator может указывать на любой ресурс в сети, декоратор не будет применяться, пока его определение загружается в текущий документ.

Разметка, которая генерируется представлениями, ограничивается чисто презентационным применением: она никогда не может запустить скрипт (в том числе встроенные обработчики событий), и она не может быть доступна для редактирования.

События в декораторах



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

Вместо этого, декораторы регистрируют обработчики событий у контроллера событий. Чтобы зарегистрировать обработчик событий, шаблон включает в себя элемент <script>. Скрипт запускается один раз, когда декоратор парсится или вставляется в документ, или загружается как часть внешнего документа.

Рис. Регистрация обработчиков событий

Регистрация обработчиков событий

Контроллер событий будет передан в скрипт в качестве значения this.

<decorator id="decorator-event-demo">
    <script>
        function h(event) {
            alert(event.target);
        }
        this.listen({selector: "#b", type: "click", handler: h});
    </script>
    <template>
        <content></content>
        <button id="b">Bar</button>
    </template>
</decorator>


Вызов функции lisnen означает, что когда кнопка будет нажата, сработает обработчик события.

Контроллер событий перенаправит событие, наступившее в на любой ноде, на которой декоратор был применён, в обработчик события.

Рис. Обработка и переназначение событий

Обработка и переназначение событий

Когда слушатель событий вызывается, значением target события является нода, на которую декоратор был применен, а не содержимое его шаблона. Например, если декоратор, указанный выше, такого содержания:

<span style="decorator: url(#decorator-event-demo);">Foo</span>

Рендерится в:

Foo[Bar]

Клик по кнопке покажет сообщение с [object HTMLSpanElement].

Переопределение свойства target необходимо, тк декоратор определяет отображение; он не влияет на структуру документа. Пока декоратор применён, свойство target переопределяется на ноду, на которую он применён.

Также, если скрипт меняет контент шаблона, изменения игнорируются, точно также, как установка textContent элемента <script> не влечет за собой выполнение скрипта ещё раз.

Декоратор не может никак изменить свой шаблон и повлиять на отображение самого себя на элемент, он может только переопределить декоратор на другой.

Примеры декораторов



Пример, как декоратор может быть применён для создания простого варианта элемента detail:


details {
    decorator: url(#details-closed);
}
details[open] {
    decorator: url(#details-open);
}

<decorator id="details-closed">
    <script>
        this.listen({
            selector: "#summary", type: "click",
            handler: function (event) {
                event.currentTarget.open = true;
            }
        });
    </script>
    <template>
        <a id="summary">
            > <content select="summary:first-of-type"></content>
        </a>
    </template>
</decorator>

<decorator id="details-open">
    <script>
        this.listen({
            selector: "#summary", type: "click",
            handler: function (event) {
                event.currentTarget.open = false;
            }
        });
    </script>
    <template>
        <a id="summary">
            V <content select="summary:first-of-type"></content>
        </a>
        <content></content>
    </template>
</decorator>


Для этого понадобилось два декоратора. Один представляет detail элемент в закрытом виде, другой в открытом. Каждый декоратор использует обработчик события клика мыши, для изменения состояния открыт/закрыт. Атрибут select элемента <element> будет рассмотрен подробнее ниже.

Пользовательские элементы



Пользовательские элементы — новый тип DOM-элементов, которые могут быть определены автором.

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

Элемент <element> определяет пользовательский элемент.

<element extends="button" name="x-fancybutton">
    …
</element>


Атрибут extends определяется элемент, функционал которого мы хотим расширить. Каждый экземпляр пользовательского элемента будет иметь tagName определённый в атрибуте extends.

Атрибут name определяет пользовательский элемент, который будет связан с этой разметкой. Пространство имён у атрибута name такое же, как у имён тэгов стандартных элементов, поэтому для устранения коллизий, используется префикс x-.

Разные браузеры, определяют HTML элементы по-разному, однако все их интерпретации руководствуются семантикой HTML.

Тк не все браузеры поддерживают пользовательские элементы, авторы должны расширять HTML элементы, которые имеют наиболее близкое значение для нового пользовательского элемента. Например, если мы определяем пользовательский элемент, который является интерактивным и реагирует на клики, выполняя некоторые действия, мы должны расширять кнопку (<button>).

Когда нету HTML элемента, семантически близкого к нужному, автор должен расширять нейтральный элемент, такой как <span>.

Представление



Пользовательский элемент может содержать шаблон:

<element extends="button" name="x-fancybutton">
    <template>
        <style scoped>
            ::bound-element { display: transparent; }
            div.fancy {
                …
            }
        </style>
        <div class="fancy">
            <content></content>
            <div id="t"></div>
            <div id="l"></div>
            <div id="b"></div>
            <div id="r"></div>
        </div>
    </template>
</element>


Если пользовательский элемент содержит шаблон, копия этого шаблона будет вставлена в теневой DOM элемента конструктором пользовательских элементов.

Теневой DOM будет описан ниже.

Использование пользовательских элементов в разметке



Т.к. пользовательские элементы использую существующие HTML тэги (div, button, option и тд), нам нужен атрибут для определения когда мы хотим использовать пользовательский элемент. Таким атрибутом является is, а значением его является название пользовательского элемента. Например:

<element extends="button" name="x-fancybutton">  <!-- definition -->
    …
</element>

<button is="x-fancybutton" onclick="showTimeClicked(event);">  <!-- use -->
    Show time
</button>


Использование пользовательских элементов в скриптах



Вы можете создать пользовательский элемент из скрипта, используя стандартный метод document.createElement:

var b = document.createElement("x-fancybutton");
alert(b.outerHTML); // will display '<button is="x-fancybutton"></button>'


Также, вы можете установить атрибут constructor у элемента <element>, чтобы явно указать название конструктора элемента, которое будет экспортировано в объект window. Этот конструктор может быть использован для создания пользовательского элемента:

<element extends="button" name="x-fancybutton" constructor="FancyButton">
    …
</element>


var b = new FancyButton();
document.body.appendChild(b);
</code></pre>


Пользовательский элемент может объявлять методы API добавляя их в свой prototype, в элементе <script>, находящимся внутри элемента <element>:

<element extends="button" name="x-fancybutton" constructor="FancyButton">
    …
    <script>
    FancyButton.prototype.razzle = function () {
        …
    };
    FancyButton.prototype.dazzle = function () {
        …
    };
    </script>
</element>

…

<script>
    var b = new FancyButton();
    b.textContent = "Show time";
    document.body.appendChild(b);
    b.addEventListener("click", function (event) {
        event.target.dazzle();
    });
    b.razzle();
</script>


Для того, чтобы обеспечить простую деградацию, this внутри элемента <script> указывает на родительский элемент типа HTMLElementElement:

<element extends="table" name="x-chart" constructor="Chart">
    <script>
        if (this === window)
            // Use polyfills to emulate custom elements.
            // …
        else {
            // …
        }
    </script>
</element>


Технически, скрипт внутри элемента <script>, когда он является вложенным в <element> или <decorator>, выполняется идентично такому вызову:

(function() {
    // code goes here.
}).call(parentInstance);


В ситуациях, когда название конструктора в объекте window неизвестно, автор пользовательского компонента может воспользоваться свойством generatedConstructor у HTMLElementElement:

<element extends="table" name="x-chart">
    <script>
        // …
        var Chart = this.generatedConstructor;
        Chart.prototype.shizzle = function() { /* … */ };
        // …
    </script>
</element>


Нельзя создать пользовательский элемент указывая is атрибут у существующего DOM-элемента. Выполнение следующего кода ничего не даст:

var div = document.createElement("div");
div.setAttribute("is", "foo");
alert(div.is); // displays null
alert(div.outerHTML); // displays <div></div>


Обновление элемента



Когда объявление пользовательского элемента будет загружено, каждый элемент с атрибутом is установленном в имя пользовательского элемента будет обновлён до пользовательского элемента. Обновление должно быть идентично удалению элемента и замене его на пользовательский элемент.

Когда каждый элемент заменяется, не всплывающее (non-bubbling), неотменяемое (non-cancellable) событие возникает на удаляющемся элементе. Скрипт, который хочет задержать взаимодействие с остальной часть документа до тех пор, пока пользовательский элемент не загрузиться может подписаться на специальное событие:

function showTimeClicked(event) {
    // event.target may be an HTMLButtonElement or a FancyButton

    if (!event.target.razzle) {
        // razzle, part of the FancyButton API, is missing
        // so upgrade has not happened yet
        event.target.addEventListener('upgrade', function (upgradeEvent) {
            showTime(upgradeEvent.replacement);
        });
        return;
    }

    showTime(event.target);
}

function showTime(b) {
    // b is FancyButton
}


Авторы, которые хотят избежать показа нестилизованного контента, могут использовать CSS для изменения отображения не заменённого, обычного элемента, пока пользовательский элемент не загрузиться.

Методы жизненного цикла



Пользовательский элемент может подписаться на четыре метода жизненного цикла:

  • created — вызов конструктора, создание экземпляра ShadowRoot из элемента <template>. При отсутствии <template>, ShadowRoot устанавливается в null.
  • attributeChanged — вызывается всякий раз, когда атрибут элемента изменяется. Аргументы: имя, старое значение, новое значение.
  • inserted — вызывается, после того, как пользовательский компонент вставлен в DOM-дерево. В данном обработчике можно подгрузить ресурсы для пользовательского конпонента или запустить таймеры.
  • removed — вызывается после того, как пользовательский элемент удалён из DOM-дерева. Тут можно остановить таймеры, которые не нужны, когда пользовательский элемент не находится в DOM-дереве.

Обработчики вызываются с this указывающим на элемент.

Обработчики inserted и removed могут быть вызваны несколько раз, каждый раз, когда пользовательский элемент вставляется и удаляется.

Подписаться на эти обработчики можно вызвав метод HTMLElementElement.lifecycle:

<element extends="time" name="x-clock">
<script>
// …

        this.lifecycle({
            inserted: function() { this.startUpdatingClock(); },
            removed: function() { this.stopUpdatingClock(); }
        });

// …
</script>
</element>


Расширение пользовательских элементов



В дополнении к HTML-элементам, можно расширить пользовательский элемент указанием имени пользовательского элемента в атрибуте extends элемента <element>:

<element extends="x-clock" name="x-grandfatherclock">
    …
</element>


Обработка ошибок



Есть несколько возможностей для обработки ошибок при рендеринге пользовательских элементов:

  • tagName элемента не соответствует значению атрибута extends пользовательского элемента, например: <div is="x-fancybutton">, но <element name="x-fancybutton" extends="button">. В этом случае, атрибут is отбрасывается во время парсинга.
  • Значение атрибута is не соответствует никакому существующему элементу. Эта ситуация рассматривается как если бы определение пользовательского элемента ещё не было загружено, и элемент будет обновлён​​, как только определение загрузится.
  • Значение атрибута extends не соответствует никакому существующему элементу. В этом случае обработка определения пользовательского элемента будет удерживаться до тех пор, пока элемент обозначенный в атрибуте extends не загрузится.
  • Значение атрибута is не начинается с x-. В данном случае, атрибут is игнорируется.
  • Значение атрибута name не начинается с x-. В данном случае, определение пользовательского элемента считается невалидным и игнорируется.


От переводчика: в следующей части мы рассмотрим применение shadow DOM в Веб-компонентах, про внешние пользовательские элементы и декораторы, и про изоляцию, ограничение и инкапсуляцию Веб-компонентов
Поделиться публикацией

Похожие публикации

Комментарии 33
    +3
    Я правильно понял, что это опять разметка, стили и код в одну кучу?
      0
      Во всех примерах на странице стандарта, html/css/js в одной куче, но я не вижу принципиальных проблем при вынесении ресурсов во внешние файлы. Стандартом это явно не запрещается.

      Например, в рассылке w3c приводили такой пример эмуляции <style scoped> для <link rel="stylesheet" />:
      <style scoped>
      @import url('/css/styles.css');
      </style>
      

      Возможность сделать так, это основная причина не вводить атрибут scoped для <link rel="stylesheet" />.

      Нужно дождаться реализации в Google Chrome и тогда уже можно говорить что-то конкретное.
      +2
      Не могли бы вы посвятить пару абзацев объяснению, что это и зачем? Это убийца HTML? Почему оно должно стать трендом?
        +1
        Это ни в коей мере не убийца HTML. Возможно я напишу статью про то зачем нужны веб-компоненты.

        Но, как минимум, вам никогда не хотелось сделать <input type=calendar>? Или свой собственный <select>? Причём с fallback'ом для старых браузеров

        Сейчас я могу порекомендовать посмотреть видео Google I/O 2012 — The Web Platform's Cutting Edge.
          –1
          Хотелось и делал как на чистом JS, так и jQuery-плагином. И многие делали.
          Это плохой пример, подавайте другой!
            +1
            Мы все люди занятые, а сегодня вообще выходной и честно, у меня нету сейчас времени придумывать и описывать пример, который для вас покажется «хорошим». На вскидку это: виджеты — Google+ Галерея, shared-файлы dropbox, Google Talk Chat на любом сайте; элементы — <input type=calendar>, <input type=barcode>; и т.д.

            В данном случае, я сделал перевод стандарта, который лично меня заинтересовал. Это и так была тяжелая работа, я ещё в комментариях доказывать, что парни из Google не недальновидны — это уж слишком.
              +1
              Во-первых, это перевод драфта, который просто драфт.
              И лейбл «Я из Google» не делает каких-то двоих чуваков гениями, но многие начинают их такими считать.
                +1
                Это драфт, который презентовали на Google I/O 2012, а я презентовал его хабрасообществу. В чем вы видите проблему?
                  0
                  Проблема в понимании, точнее в его отсутствии. Если Вы просто увидели что-то новое «от гугла» и, не пытаясь понять что это и зачем, перевели на русский — спасибо за перевод и больше вопросов к Вам нет. Но я предполагаю, что если кто-то, не являющийся профессиональным переводчиком, берётся что-то переводить, тем более что-то новое и не тривиальное, то это вызвано тем, что он понимает то, что переводит, и ему оно нравится.

                  Поскольку после прочтения Вашего перевода у меня не появилось понимания что это и зачем (как и у многих других комментирующих Ваш перевод), то возникает вполне логичное желание попросить автора перевода это объяснить — опять же, предполагая что он сам это уже понимает.

                  Какую проблему решает этот стандарт? Реальная это проблема, или надуманная? Есть ли другие подходы к решению этой проблемы? Чем этот стандарт от них отличается (плюсы и минусы)? — Если Вы можете ответить на эти вопросы, то это стоило сделать, вероятно, в начале статьи. Иногда эти ответы очевидны, но, судя по текущим комментариям — это не тот случай.
                    0
                    Проблема есть. Она заключается в необходимости модульного описания определённого элемента веб-интерфейса. Чтобы для него был механизм описания разметки, стилей и логики.

                    И тут начинаются нюансы. С одной стороны хочется чтобы оно было «в одном месте», с другой стороны когда оно в одном месте, не так уж и радует потому что «как-то в кучу».

                    Это «новое от гугла» похоже одна из попыток решить проблему. У меня в процессе чтения возникло как-раз ощущение «как-то в кучу всё».
                      0
                      С одной стороны хочется чтобы оно было «в одном месте», с другой стороны когда оно в одном месте, не так уж и радует потому что «как-то в кучу».

                      А как по Вашему должно быть, чтобы было не «в кучу»?
                      0
                      Я слежу за этой технологией уже почти год и понимаю зачем и для чего она нужна. После презентации Гуглом, я решил поделится я сообществом.
                      Примеры использования данной технологии достойны отдельной статьи, которую я возможно напишу в ближайшее время, после того, как закончу с переводом и узнаю ответы на некоторые вопросы озвученные тут в обсуждении у разработчиков стандарта.
                      Поймите меня правильно, пока данный стандарт не реализован в Хроме, я не могу отвечать на вопросы в реал-тайме, а вопросы будут.
                        +1
                        … пока данный стандарт не реализован в Хроме…

                        Этот момент не очень понятен. У Вас по этому поводу какая информация есть?
                        Просто до какого-то уровня стандарт там уже, похоже, рализован, т.к. есть dart-web-components.
                        Или Вы ждете реализации хотя бы в dev-канале?
                          0
                          Я жду, когда появится в десктопном Chromium, тогда можно будет говорить о серьёзности намерений Гугла в отношении этого стандарта.
          +1
          Я этого тоже не понял. Пока это выглядит как попытка запихнуть что-то подобное XML + XSLT в один файл и сверху приправить JS для наглядности. Смысла не вижу.
            +1
            это попытка XBL (http://www.w3.org/TR/xbl/), который реализован и обкатан в мозилле, но никто не собирается его поддерживать, переложить на html5. получилась хрень, потому как:
            1. нет возможности плавной деградации для не поддерживающих эту технологию браузеров, а также нет возможности сделать js-эмуляцию оной (xbl можно транслировать в htc и сделать эмуляцию на js, но с некоторыми ограничениями)
            2. описание компонент идёт прямо в html, а не выносится в отдельные подключаемые кэширующиеся ресурсы (в xbl это выносится by design)
            3. крайний примитивизм шаблонов (в xbl не сильно лучше)
            4. пихание разных языков (js, css, html) в одну кучу без возможности разнести их по отдельным файлам (в xbl даже хуже — необходимо амперсанды в js экранировать).
            5. сволочи, они украли у меня название мета-фреймворка)
            зато очень в тренде «html5» который стал символом велосипеда. или наоборот о0
              0
              1. Эта тема для progressive enhancement, то есть все должно работать изначально без этого, а эта тема добавляет плюшки.
              2. Выносится и подключается через <link rel=«components» href=«enhancements.html»>
              3. Видимо это потому что эти шаблоны оборачивают существующий markup или его части.
              4. Все то же самое что и html

              Мне кажется у данной идеи другие проблемы, основная — слишком запутанно и сложно. В примерах все замечательно, но если представить что таким образом будет собран большой проект… В любом случае, сейчас это на уровне идеи — поглядим к чему это придет.
                0
                1. да как ни обзывай — там этого нет. по стандарту содержимое template не должно рендериться, но текущие браузеры ничего про template не знают и рендерить будут. аналогично со style scoped — стили будут применяться ко всему документу. и тому подобные несоместимости. а раз уж мы делаем несоместимо, то можно сделать и по уму, а не притягивать за уши префикс «x-» или дважды указывать, что x-fancybutton является расширением button и кидать ошибку, если разработчик это недокопипастил.

                2. тогда возникает вопрос: чем эта поделка лучше xbl или htc? потому что они обладают всем известным «фатальным недостатком»? ещё опере надо реализовать свои «компоненты» и тогда у каждого движка будет своя их реализация)

                3. ну да, и из-за этого приходится городить кучу костылей — сначала рендерим шаблон, а потом скриптом его перефигачиваем.
            0
            Суперская вещь.

            Это очень похоже на wpf/xaml подход. Это наверное лучшее решение в плане работы с разметкой на текущий момент.
            Там элементы несут на себе только одну ответственность: логический элемент в разметке. То есть мы знаем что кнопка ведет себя как кнопка: ее можно кликнуть, но визуально она может выглядеть как угодно: например как дроп даун. Там есть понятие style — которое примерно соответствует css в html. И понятие template — которое соответствует декоратору из статьи и позволяет определить визуальное отображение любого элемента. Также можно определять свои смысловые элементы с собственным поведением.

            То есть в html мы сможем абстрагироваться от того как выглядят те или иные элементы и только думать о том, какой по смыслу элемент выбрать в рамках данной разметки. Дальше передаем дизайнеру и он сможет превратить этот смысловой элемент во что хочет. Решение позволит реально отделить труд дизайнера и верстальщика/веб программиста.
            И позволит создавать элементы с кастомным поведением, что облегчит архитектуру любого web проекта.

            Единственное — в данный момент предложенное решение выглядит не очень опрятно из-за ограничений текущего примитивного html подхода к верстке. Жаль что декораторы не смогут запускать скрипты и определять редактирование элемента.

            Но вообще я уверен, что примерно так и будет выглядеть html в будущем.
              +1
              А как же первое правило разработки интерфейсов — интуитивность? Кнопка должна выглядеть как кнопка.
                +1
                Ну самый простой пример: кнопка которая выглядит как ссылка. Это часто может быть адекватно в рамках определенного стиля. Другой пример: чек бокс в виде текста или картинки. То есть кликаете на зеленую картинку — скажем какой то процесс запустился и картинка сменилась на красную, кликаете еще раз — процесс остановился и картинка сменилась на зеленую.

                В принципе правило будет работать — вопрос лишь в том, что такое интуитивный интерфейс. Например интерфейс ribbon в msoffice сильно отличается от интерфейсов предыдущего поколения. Но прошло время, люди привыкли и теперь он уже интуитивен. Многие офисные приложения даже в вебе используют этот стиль.

                Я себе так все вижу что крупные игроки в вебе будут диктовать такие «интуитивные» стили. И они будут разными по крайней мере для разных сфер деятельности веб сервисов.
                Главное чтобы они вообще могли эволюционировать хоть как то. В данный момент html загоняет в очень узкие рамки.
              0
              Чё-то разработчикам Google совсем там скучно и клонит придумать какой-нить mess.
              Половина примеров кода в драфте выглядит абсурдно и даже поясняется не менее абсурдными комментариями.
              Я пытался понять всё это, но, пожалуй, я продолжу работать по уютной старинке :-)
                0
                Не хочется дублировать текст, ответил выше.
                habrahabr.ru/post/152001/#comment_5161636
                  0
                  Я там тоже ответил.
                  Егор, а какой Ваш основной профиль?
                  На чём писали последние пару-тройку лет?
                    0
                    Такие вопросы в личку
                      0
                      Интимный вопрос?! :)))
                      0
                      Также всю нужную информацию вы можете узнать из моих профилей на хабре и github
                        –3
                        Да, я уже изучил код на Гитхабе.
                        И желания что-то обсуждать у меня больше не осталось :))
                          +1
                          Есть какие-то проблемы с моим кодом? Я готов выслушать критику.
                            0
                            Чего вы? Код организован довольно грамотно, с достаточными комментами. Все бы так писали…
                    0
                    Очень интересная штука, натыкался пару месяцев назад на демо с подключением индикатора загрузки таким образом, надеюсь что идея приживется.
                      0
                      Здорово, конечно. Но маловероятно, что это:
                      а) есть стандарт и он будет реализован во всех броузерах
                      а) «может стать трендом в ближайшие несколько лет»

                      Ни HTC (Internet Explorer <9.0), ни XBL (Gecko <1.9), ни XBL2 (тоже стандарт! и тоже от Google) трендами не стали, выглядили тем не менее более красиво.

                      Да, похожий велосипед, но работающий во всех броузерах: Ample SDK

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое