Front-end Rails-приложений
   основанный на БЭМ



             Дмитрий Карпунин, Evrone.com
FRONT-END RAILS-ПРИЛОЖЕНИЙ

   views
   helpers
   stylesheets
   images
   javascripts

   controllers
   locales
СЕМАНТИЧЕСКАЯ ВЁРСТКА

<body>
  <div id="header">
    <ul id="main_menu">
       <li class="menu_item">...</li>
       ...
    </ul>
  </div>
  <div id="content">...</div>
  <div id="footer">...</div>
</body>
БЭМ — БЛОК, ЭЛЕМЕНТ, МОДИФИКАТОР


<div class="b-post b-post_favorite">
  <div class="b-post__author">
    <div class="avatar">...</div>
    ...
  </div>
  <div class="b-post__content">
    <h3 class="title">...</h3>
    ...
  </div>
</div>
ПОПРОБУЕМ УПРОСТИТЬ
<div class="b-post favorite">
  <div class="author">
    <div class="avatar">...</div>
    ...
  </div>
  ...
    <a class="g-iconed favorite">В избранное</a>
</div>


.g-iconed {
  padding-left: 20px;
  background: left center no-repeat;
}
.g-iconed.favorite {
  background-image: url("/images/icons/favorite.png");
}
ПОЛЬЗОВАТЕЛЬ IE6 В ШОКЕ
<div class="b-post favorite">
  <div class="author">
    <div class="avatar">...</div>
    ...
  </div>
  ...
    <a class="g-iconed favorite">В избранное</a>
</div>


.g-iconed {
  padding-left: 20px;
  background: left center no-repeat;
}
.g-iconed.favorite {
  background-image: url("/images/icons/favorite.png");
}
СТАТИСТИКА IE 6-8, РФ,
   LIVEINTERNET.RU
IE 6-8, ЕВРОПА, GS.STATCOUNTER.COM
БЭМ НА ПРАКТИКЕ
C) .c-placeholder, .c-blue, .c-link, ...
  $c-placeholder, $c-blue, $c-link, ...

G)
1) глобальные модификаторы:
  .g-line, .g-inline-block, .g-font_accident, ...
   g-line, inline-block, g-font_accident, ...
2) микроструктуры:
  .g-iconed.user, .g-thumb.size_50x50, ...
  g_thumb(@user.image.url(:medium), "50x50")

L)   .l-page, .l-profile, l-users-show, ...
     .l-page__footer, .l-profile__left-content, ...
     @import "blocks/users/b-friends";

B)   .b-post, .b-post_favorite, .b-post__author, ...
     div_for(post, :class => "b-post") => #post_42
SASS
                         http://sass-lang.com/




 /config/environment.rb

Sass::Plugin.options[:template_location] = "./app/stylesheets"
Sass::Plugin.options[:css_location] = "./public/stylesheets/compiled"
if RAILS_ENV == "production"
  Sass::Plugin.options[:style] = :nested
else
  Sass::Plugin.options[:style] = :expanded
  Sass::Plugin.options[:debug_info] = true
end


                                          FireSass for Firebug
СТРУКТУРА СТИЛЕЙ

/app/stylesheets/
    import/
        *.scss
    global/
        *.scss
    layouts/
        l-*.scss
    blocks/
        [%C%/[%A%/]]b-*.scss
/APP/STYLESHEETS/IMPORT/

base.scss                       константы проекта
$layout-page-width: 1000px;
$layout-side-width: 240px;

$c-black: #333333;
$c-gray: #777777;
$c-light-gray: #999999;
$c-blue: #2266aa;



mixins.scss                        базовые миксины
                                          @mixin g-line {
                                            *zoom: 1;
@mixin opacity($value: 0.5) {               _height: 0;
  opacity: $value;                          &:after {
  $value: $value * 100;                       content: " ";
  filter: progid:DXImageTransform.            display: block;
    Microsoft.Alpha(opacity=#{$value});       clear: both;
}                                             height: 0;
                                            }
                                          }
/APP/STYLESHEETS/GLOBAL/

reset.scss

fundamental.scss

.g-line {
  @include g-line;
}

reserved.scss

.bold {
  font-weight: bold;
}

.placeholder {
  color: $c-placeholder;
}
/APP/STYLESHEETS/GLOBAL/
structures.scss

@import "include/base";

.g-iconed {
  padding-left: 20px;
  background: transparent 0 0 no-repeat;
}

@mixin _g-iconed_type($name) {
  .g-iconed.#{$name} {
    background-image: url("#{$icons-path}/#{$name}.png");
  }
}

@include _g-iconed_type(user);
@include _g-iconed_type(email);

layout.scss

all.scss
/app/views/users/show.haml

- content_for :head,
          stylesheet_link_tag("compiled/layouts/l-users-
show");


/app/stylesheets/layouts/l-users-show.scss

@import "blocks/users/b-friends";


/app/stylesheets/blocks/users/b-friends.scss

.b-friends {
  .title {...}
  .users-list {...}
  ...
}

/public/javascripts/users/b-friends.js

$( function () {
  var jFriends = $('.b-friends');
  ...
} );
ВОПРОСЫ? 0_O

Evrone.ru / BEM for RoR

  • 1.
    Front-end Rails-приложений основанный на БЭМ Дмитрий Карпунин, Evrone.com
  • 2.
    FRONT-END RAILS-ПРИЛОЖЕНИЙ  views  helpers  stylesheets  images  javascripts  controllers  locales
  • 3.
    СЕМАНТИЧЕСКАЯ ВЁРСТКА <body> <div id="header"> <ul id="main_menu"> <li class="menu_item">...</li> ... </ul> </div> <div id="content">...</div> <div id="footer">...</div> </body>
  • 4.
    БЭМ — БЛОК,ЭЛЕМЕНТ, МОДИФИКАТОР <div class="b-post b-post_favorite"> <div class="b-post__author"> <div class="avatar">...</div> ... </div> <div class="b-post__content"> <h3 class="title">...</h3> ... </div> </div>
  • 5.
    ПОПРОБУЕМ УПРОСТИТЬ <div class="b-postfavorite"> <div class="author"> <div class="avatar">...</div> ... </div> ... <a class="g-iconed favorite">В избранное</a> </div> .g-iconed { padding-left: 20px; background: left center no-repeat; } .g-iconed.favorite { background-image: url("/images/icons/favorite.png"); }
  • 6.
    ПОЛЬЗОВАТЕЛЬ IE6 ВШОКЕ <div class="b-post favorite"> <div class="author"> <div class="avatar">...</div> ... </div> ... <a class="g-iconed favorite">В избранное</a> </div> .g-iconed { padding-left: 20px; background: left center no-repeat; } .g-iconed.favorite { background-image: url("/images/icons/favorite.png"); }
  • 7.
    СТАТИСТИКА IE 6-8,РФ, LIVEINTERNET.RU
  • 8.
    IE 6-8, ЕВРОПА,GS.STATCOUNTER.COM
  • 9.
    БЭМ НА ПРАКТИКЕ C).c-placeholder, .c-blue, .c-link, ... $c-placeholder, $c-blue, $c-link, ... G) 1) глобальные модификаторы: .g-line, .g-inline-block, .g-font_accident, ... g-line, inline-block, g-font_accident, ... 2) микроструктуры: .g-iconed.user, .g-thumb.size_50x50, ... g_thumb(@user.image.url(:medium), "50x50") L) .l-page, .l-profile, l-users-show, ... .l-page__footer, .l-profile__left-content, ... @import "blocks/users/b-friends"; B) .b-post, .b-post_favorite, .b-post__author, ... div_for(post, :class => "b-post") => #post_42
  • 10.
    SASS http://sass-lang.com/ /config/environment.rb Sass::Plugin.options[:template_location] = "./app/stylesheets" Sass::Plugin.options[:css_location] = "./public/stylesheets/compiled" if RAILS_ENV == "production" Sass::Plugin.options[:style] = :nested else Sass::Plugin.options[:style] = :expanded Sass::Plugin.options[:debug_info] = true end FireSass for Firebug
  • 11.
    СТРУКТУРА СТИЛЕЙ /app/stylesheets/ import/ *.scss global/ *.scss layouts/ l-*.scss blocks/ [%C%/[%A%/]]b-*.scss
  • 12.
    /APP/STYLESHEETS/IMPORT/ base.scss константы проекта $layout-page-width: 1000px; $layout-side-width: 240px; $c-black: #333333; $c-gray: #777777; $c-light-gray: #999999; $c-blue: #2266aa; mixins.scss базовые миксины @mixin g-line { *zoom: 1; @mixin opacity($value: 0.5) { _height: 0; opacity: $value; &:after { $value: $value * 100; content: " "; filter: progid:DXImageTransform. display: block; Microsoft.Alpha(opacity=#{$value}); clear: both; } height: 0; } }
  • 13.
    /APP/STYLESHEETS/GLOBAL/ reset.scss fundamental.scss .g-line { @include g-line; } reserved.scss .bold { font-weight: bold; } .placeholder { color: $c-placeholder; }
  • 14.
    /APP/STYLESHEETS/GLOBAL/ structures.scss @import "include/base"; .g-iconed { padding-left: 20px; background: transparent 0 0 no-repeat; } @mixin _g-iconed_type($name) { .g-iconed.#{$name} { background-image: url("#{$icons-path}/#{$name}.png"); } } @include _g-iconed_type(user); @include _g-iconed_type(email); layout.scss all.scss
  • 15.
    /app/views/users/show.haml - content_for :head, stylesheet_link_tag("compiled/layouts/l-users- show"); /app/stylesheets/layouts/l-users-show.scss @import "blocks/users/b-friends"; /app/stylesheets/blocks/users/b-friends.scss .b-friends { .title {...} .users-list {...} ... } /public/javascripts/users/b-friends.js $( function () { var jFriends = $('.b-friends'); ... } );
  • 16.