#328 Twitter Bootstrap Basics
- Download:
- source codeProject Files in Zip (52.1 KB)
- mp4Full Size H.264 Video (32.3 MB)
- m4vSmaller H.264 Video (14.4 MB)
- webmFull Size VP8 Video (14.4 MB)
- ogvFull Size Theora Video (35.7 MB)
트위터 부트스트랩은 멋진 웹어프리케이션을 신속하게 만들 수 있게 도와 줍니다. 이 트위터 부트스트랩은 레이아웃, 페이지이동 메뉴바(네비게이션), 폼 그리고 기타 많은 것들을 만들 수 있게 다양한 CSS와 자바스크립트를 제공합니다. 예를 들어, 트위터 부트스트랩 홈페이지를 방문하여 브라우저 창의 폭을 변경하면 웹페이지의 레이아웃이 변경된 폭에 맞춰 최적의 상태로 보여질 것입니다. 이것은 모바일 디바이스에서 웹어플리케이션을 이용할 때 더 좋은 경험을 할 수 있게 해 줍니다.
부트스트랩이 지원하는 모든 기능을 알아보기 위해 시간을 내서 트위터 부트스트랩 웹사이트를 방문해 볼 것을 권합니다. 그러나 이번 연제에서는 레일스 어플리케이션에서 부트스트랩을 사용하는 방법에 대해서 알아 보도록 하겠습니다. 한가지 옵션으로는 “Download Bootstrap” 링크를 클릭해서 CSS와 자바스크립트 파일을 다운로드한 후, 필요한 파일만 /app/assets
디렉토리로 옮기는 것입니다. 그러나 레일스를 사용하고 있다면 이것은 최선의 방법이 되지 못합니다. 트위터 부트스트랩은 일종의 CSS 전처리기(preprocessor)인 LESS를 사용해서 작성되었으며, LESS는 레일스에서 사용하는 SASS와 매우 비슷합니다.
트위터 부트스트랩으로부터 최상의 유연성을 얻기 위해서는, LESS와 같은 전처리기에서 만들어 주는 컴파일된 정적 파일형태로 사용하는 것보다는 트위터 부트스트랩을 이러한 동적인 언어(전처리기, LESS나 SASS와 같은)로 직접 사용하는 것이 가장 좋은 방법입니다. 레일스에서 LESS를 사용하기 위해서는 몇가지 루비 젬의 도움이 필요합니다. 부트스트랩과 레일스를 통합하기 위해 사용할 수 있는 젬이 몇가지 있지만, 이 연제에서는 twitter-bootstrap-rails gem을 사용할 것입니다. 그러나 나중에 몇가지 대안에 대해서도 언급하도록 하겠습니다. 이 젬을 선택하게 된 것은 LESS를 바로 사용할 수 있고 작업을 시작할 때 우리를 편하게 해 주는 몇가지 제너레이터를 제공해 주기 때문입니다. 아직 작업할 레일스 어플리케이션이 없긴 하지만 여기서 미리 좀 살펴보도록 하겠습니다.
레일스 어플리케이션 생성 후 부트스트랩 추가하기
store
란 이름의 레일스 어플리케이션을 시작해 보겠습니다. 그리고 Product
모델을 scaffold 제너레이터를 이용해서 생성하여 작업할 대상을 준비합니다.
$ rails new store $ cd store $ rails g scaffold product name price:decimal --skip-stylesheets $ rake db:migrate
scaffold에서 만들어 주는 CSS 대신 부트스트랩의 CSS를 사용하고자 하기 때문에 scaffold 에서 --skip-stylesheets
옵션을 사용한 것을 주목하기 바랍니다. 또한 데이터베이스를 마이그레션하여 product 테이블을 생성했습니다. 아래에 scaffold를 이용하여 생성된 페이지가 있습니다. 아직 아무런 스타일이 적용되지 않아 그렇게 이쁘게 보이지 않습니다. 이제 트위터 부트스트랩을 적용해 보도록 하겠습니다.
첫번째 단계는 gemfile의 assets
그룹에 twitter-bootstrap-rails
젬을 추가해 줍니다. 이 젬은 단지 asset pipeline만이 사용할 것이기 때문에 이 그룹에서만 필요한 것입니다. 운영서버에서 정적상태의 precompile된 상태로 사용할 것이라면 이것은 필요없을 것입니다.
# Gems used only for assets and not required # in production environments by default. group :assets do gem 'sass-rails', '~> 3.2.3' gem 'coffee-rails', '~> 3.2.1' # See https://github.com/sstephenson/execjs#readme for more supported runtimes # gem 'therubyracer' gem 'uglifier', '>= 1.0.3' gem 'twitter-bootstrap-rails' end
다음으로 bundle
명령을 실행해서 관련 젬과 함께twitter-bootstrap-rails
을 설치할 것입니다. 이 젬은 libv8
과 less-rails
젬을 포해서 많은 연관 젬이 있는데 이것들은 어플리케이션이 LESS문을 해독할 수 있게 해 줍니다. 이제 부트스트랩 젬을 설치했기 때문에 전용 제너레이터를 이용하여 실제로 설치해 보도록 하겠습니다.
$ rails g bootstrap:install insert app/assets/javascripts/application.js create app/assets/javascripts/bootstrap.js.coffee create app/assets/stylesheets/bootstrap_and_overrides.css.less gsub app/assets/stylesheets/application.css gsub app/assets/stylesheets/application.css
이렇게 하면 /app/assets/
디렉토리에 부트스트랩이 셋업됩니다. 생성된 된 핵심 파일은 bootstrap_and_overrides.css.less
입니다. 이 파일이 부트스트랩을 로드해 주게 되고 어플리케이션에 맞게 스타일링 작업을 변경할 수 있는 최적의 장소가 되는 것입니다. 서버를 재시작한 후 해당 페이지를 다시 로드하면 이미 스타일이 더 좋아 보이기 시작하지만 아직 해야할 것이 많습니다.
레이아웃 향상시키기
우선 어플리케이션의 레이아웃에 초점을 맞추어 설명하겠습니다. twitter-bootstrap-rails
젬은 bootstrap:layout
제너레이터를 제공해 주기 때문에 이를 이용하면 레이아웃 파일을 만들 수 있습니다. 그러나 여기서는 이것을 사용하지 않을 것입니다. 대신에 트위터 부트스트랩이 동작하는 기전을 잘 이해할 수 있도록 레이아웃을 변경하는 과정을 진행하도록 하겠습니다.
부트스트랩에는 fixed와 fluid, 두가지 종류의 레이아웃 형식이 있습니다. fixed형 레이아웃은 픽셀단위로 폭을 지정하는 반면에, fluid형 레이아웃은 브라우저의 폭에 따라 자동으로 확장될 것입니다. div
태그의 클래스로 container
또는 container-fluid
를 지정하여 어떤 레이아웃이 사용될 것인지를 결정하게 될 것입니다. 여기서는 fixed형 레이아웃을 사용할 것이기 때문에, 레이아웃 파일의 body
안에 container
클래스를 가진 div
태그를 추가할 것입니다.
<!DOCTYPE html> <html> <head> <title>Store</title> <%= stylesheet_link_tag "application", :media => "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> </head> <body> <div class="container"> <%= yield %> </div> </body> </html>
트위터 부트스트랩은 12컬럼의 격자 시스템을 사용합니다. 컬럼 폭을 지정하여 컬럼을 이용한 레이아웃을 작성을 쉽게 해 줍니다. 이 레이아웃은 반응형(responsive)이어서 브라우저의 폭을 줄일 때 레이아웃이 그에 따라 자동으로 변경될 것입니다. 디자인시 사이드바가 필요하며 페이지 폭의 25%가 되게 그 폭을 조절하고자 한다면 아래와 같이 레이아웃 파일을 수정하여 원하는 작업을 수행할 수 있습니다. 아래는 사이드바에 약간 정적인 텍스트내용를 추가해 놓은 상태입니다.
"div class="container"> <div class="row"> <div class="span9"><%= yield %></div> <div class="span3"> <h2>About Us</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div> </div> </div>
이제 페이지를 다시 로드하면 두개의 컬럼이 있는 레이아웃을 보게 될 것입니다.
페이지이동 메뉴바(Navigation Bar) 추가하기
다음으로 페이지 상단에 페이지이동 메뉴바를 추가해서 사이트내 이동을 위한 몇가지 링크를 위치시키도록 하겠습니다. documentation 내용 중 components 섹션에는 트위터 부트스트랩이 제공하는 다양한 관련 옵션들을 제공해 주는데, 그 중에는 navbar라는 것이 있습니다. 이 navbar는 우리의 입맛에 맞게 변경할 수 있어서 링크, 드롭다운, 검색필드 등을 추가할 수 있습니다. 이 문서에는 각 항목을 추가하는 방법에 대한 좋은 예제 코드들이 있습니다. 여기서는 레이아웃 페이지의 body 상단에 navbar를 추가해 보도록 하겠습니다.
<div class="navbar navbar-fixed-top"> <div class="navbar-inner"> <div class="container"> <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </a> <a class="brand" href="#">Some Store</a> <div class="nav-collapse"> <ul class="nav"> <li><%= link_to "Browse Products", products_path %></li> <li><%= link_to "Price List" %></li> <li><%= link_to "Contact Us" %></li> <li><%= link_to "Cart" %></li> </ul> </div> </div> </div> </div>
위의 페이지이동 메뉴바에는 브랜드명을 표시하는 섹션과 위치지정을 위한 링크(placeholder)가 있습니다. 상단에 있는 섹션은 흥미롭습니다. 이것은 브라우저 크기가 변경될 때 페이지이동 메뉴바의 축소 동작을 처리합니다. 이제 페이지를 다시 로딩하면 새로운 navbar를 보게 될 것입니다.
페이지이동 메뉴바의 축소된 형태를 눈여겨 보기 바랍니다. 이것은 브라우저 창의 폭이 800px 정도로 설정되어 있어서 전체 페이지를 보여줄 수 있는 정도로 충분하지 못하든 것을 의미합니다. 창의 폭을 크게 한다면 페이지이동 메뉴바가 다시 보이게 될 것입니다.
그러나 이렇게 할 때 한가지 문제가 있습니다. 페이지의 상단부가 navbar에 가려져 버린다는 것입니다. 이것은 fixed형 레이아웃의 부작용이며, 문서내용을 참조하면, Bootstrap CSS와 responsive CSS 사이에서 body
엘리먼트의 상단에 최소 40픽셀정도의 padding값을 설정해 주면 해결할 수 있습니다. 이러한 작업은 bootstrap_and_overrides
파일에서 해 주면 됩니다. 즉, 이 파일에는 bootstrap
과 responsive
파일이 포함되기 때문에 이 둘 사이에 padding 값을 더해주면 됩니다.
@import "twitter/bootstrap/bootstrap"; body { padding-top: 60px; } @import "twitter/bootstrap/responsive"; // Set the correct sprite paths @iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png'); @iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png'); // Your custom LESS stylesheets goes here // // Since bootstrap was imported above you have access to its mixins which // you may use and inherit here // // If you'd like to override bootstrap's own variables, you can do so here as well // See http://twitter.github.com/bootstrap/less.html for their names and documentation // // Example: // @linkColor: #ff0000;
이제 페이지를 다시 로드하면 페이지 상단이 더 이상 navbar 뒤로 사라지지 않을 것입니다.
head 부분에 대한 최종 조절작업
이제 어플리케이션의 레이아웃 파일은 훨씬 더 완벽해 졌지만, 어떤 환경에서도 제대로 작동하기 위해서는 head 부분에 추가해 주어야할 몇가지 사항이 있습니다.
<head> <title>Store</title> <!--[if lt IE 9]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script> <![endif]--> <%= stylesheet_link_tag "application", :media => "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head>
여기서 추가한 첫번째는 인터넷 익스플로러의 이전버전에서의 HTML5 지원을 보다 좋게 향상시키기 위한 것입니다. 두번째 것은 뷰포트 meta
로써 모바일 디바이스에서 반응형(responsive) 디자인의 동작을 교정하기 위한 것입니다.
뷰 향상시키기
그렇다면 어프리케이션내의 다른 뷰에 대해서는 어떻게 될까요. 트위터 부트스트랩은 많은 기능을 제공해 주어 scaffold가 생성한 코드를 보기 좋게 만들 수 있습니다. 먼저, product 레코드를 몇개 추가해서 더 많은 데이터로 작업을 해 보겠습니다.
다음으로 트위터 부트스트랩을 이용해서 이 페이지의 모양의 향상시켜 보도록 하겠습니다. 직접 각각을 수정하지 않고 젬에서 제공하는 제너레이터 중 하나를 사용할 것입니다. 이 제너레이터는 themed
라고 하는데 scaffolding한 상태에서 작동하도록 디자인되어 있어서 해당 scaffold의 이름을 넘겨 주어야 합니다. 또한 이 때 -f
옵션을 명시해 주어 생성된 뷰 파일들을 강제로 겹쳐스도록 해 줍니다.
$ rails g bootstrap:themed products -f
이제 products 페이지를 다시 로드하면 훨씬 더 좋게 보일 것입니다. 테이블이 훨신 깔끔해 지고 “edit” 와 “destroy” 링크가 텍스트 링크가 아니라 버튼처럼 보이게 됩니다.
이와 같은 변화가 하나의 product를 보고 편집하기 위한 페이지에도 적용되었습니다. 이 템플릿의 소스코드를 보게 되면 어떻게 동작하는지를 정확하게 알 수 있을 것입니다.
<h1>Products</h1> <table class="table table-striped"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Created at</th> <th>Actions</th> </tr> </thead> <tbody> <% @products.each do |product| %> <tr> <td><%= product.id %></td> <td><%= link_to product.name, product_path(product) %></td> <td><%= product.created_at %></td> <td> <%= link_to 'Edit', edit_product_path(product), :class => 'btn btn-mini' %> <%= link_to 'Destroy', product_path(product), :method => :delete, :confirm => 'Are you sure?', :class => 'btn btn-mini btn-danger' %> </td> </tr> <% end %> </tbody> </table> <%= link_to 'New', new_product_path, :class => 'btn btn-primary' %>
몇가지 CSS 클래스가 products를 표시하는 테이블에 추가되었습니다. 이와 비슷하게 “Edit” 와 “Destroy” 링크에도 추가되어 보기가 좋아졌습니다. 가장 큰 변화는 하나의 product를 생성하거나 수정하는 폼 partial 입니다.
<%= form_for @product, :html => { :class => 'form-horizontal' } do |f| %> <fieldset> <legend><%= controller.action_name.capitalize %> Product</legend> <div class="control-group"> <%= f.label :name, :class => 'control-label' %> <div class="controls"> <%= f.text_field :name, :class => 'text_field' %> </div> </div> <div class="control-group"> <%= f.label :price, :class => 'control-label' %> <div class="controls"> <%= f.text_field :price, :class => 'text_field' %> </div> </div> <div class="form-actions"> <%= f.submit nil, :class => 'btn btn-primary' %> <%= link_to 'Cancel', products_path, :class => 'btn' %> </div> </fieldset> <% end %>
위의 코드는 scaffold 제너레이터가 생성한 코드와 비교해 볼 때 상당히 많이 변경된 것이어서, 트위터 부트스트랩으로 폼을 정말 멋지게 보이게 하는 방법에 대한 좋은 예로서 역할을 하기도 합니다.
자 이제, 이 연제을 마무리할 시간이 다 되었는데, 앞서 twitter-bootstrap-rails
젬의 몇가지 대안에 대해서 언급하겠다고 말한 바 있습니다. Ruby Source에 있는 이 기사를 보면 이런 것들에 대한 리스트가 있습니다. 여기에서는 트위터 부트스트랩이 동작하는 방법과 레일스와 통합하여 사용할 수 있는 여러가지 옵션과 젬들에 대한 설명이 있습니다.