Skip to content

Instantly share code, notes, and snippets.

@bertBruynooghe
Last active December 9, 2016 16:35
Show Gist options
  • Save bertBruynooghe/8cc4bb982f62591e942ba917bf1119e6 to your computer and use it in GitHub Desktop.
Save bertBruynooghe/8cc4bb982f62591e942ba917bf1119e6 to your computer and use it in GitHub Desktop.

Lean HTML

in a Rails context


Lean HTML

  • {:.fragment}readability
  • {:.fragment}ease to debug

{:.fragment} …while not compromising UX

Extracted from a personal project which I use several times a day. Extracted from cleaning unified post apps

#Lean HTML

  • HTML Templating Languages
  • {:.fragment}Tags
  • {:.fragment}Javascript
  • {:.fragment}Styling
  • {:.fragment}Accessibility


HTML Templating Languages


HTML.erb

<p id="notice"><%= notice %></p>
<p><strong> Name: </strong><%= @ingredient.name %></p>
<%= link_to 'Edit', edit_ingredient_path(@ingredient) %>
|
<%= link_to 'Back', ingredients_path %>

HAML

%p#notice
  = notice
%p
  %strong Name:
  = @ingredient.name
= link_to 'Edit', edit_ingredient_path(@ingredient)
'|
= link_to 'Back', ingredients_path

HAML

  • More concise than HTML
  • {:.fragment}Online conversion to/from HTML.erb

SLIM

  p#notice = notice
  p
    strong Name:
    = @ingredient.name
      = link_to 'Edit', edit_ingredient_path(@ingredient)
  '|
  = link_to 'Back', ingredients_path

SLIM

  • Even more concise
  • Online conversion [from](http://erb2slim.com) HTML.erb only, conversion to HTML.erb command line only.

HTML.erb > HAML > SLIM

Increasingly:

  • {:.fragment}difficult understanding the code
  • {:.fragment}difficult debugging in the browser
  • {:.fragment}difficult getting the team on board
  • {:.fragment}difficult getting new hires on board
  • {:.fragment}less support from IDE


Tags

{:.fragment} Semantic tags


Buttons vs. links

  • {:.fragment}Choice based on the user's mental model
    • {:.fragment}is the user considering it as an operation in the webapp?
    • {:.fragment}is it a link to a document/page/… ?
  • {:.fragment}links can be opened in a separate tab/window; buttons cannot
  • {:.fragment}Code it as <button> or <a href=…> accordingly, or use link_to, button_to, submit Rails helpers

Lists vs. Tables

  • {:.fragment}Does it make sense to read the data column- AND row-wise?
  • {:.fragment}Are you using tables purely based on layout considerations?
  • {:.fragment}Does the user need custom sorting?

Forms

Use Rails Forms!

  • {:.fragment}Cross-site request forgery (CSRF) protection
  • {:.fragment}Stateless

FormBuilder

{:.fragment}

<%= form_for @meal do |f| %>
  <%= f.local_datetime_select :consumption_time %>
<% end %>

{:.fragment} form_builder.rb

class FormBuilder < ActionView::Helpers::FormBuilder
  def local_datetime_select(method)
    @template.datetime_select(@object_name, method)
      .concat(@template.content_tag(:span) { @object.send(method).zone })
  end
end

{:.fragment} intializers/form_builder.rb

Rails.application.configure do
  config.action_view.default_form_builder = "FormBuilder"
end

Forms - I18n

<% ingredient_form.label :name %>
<% ingredient_form.text_input :name %>
<% ingredient_form.submit %>

en.yml

en:
  <activerecord/activemodel>:
    models:
      <model_name>: …
    attributes:
      <model_name>:
        <attribute_name>: <caption>
  helpers:
    submit:
      <action>: "… %{model}"
      <model_name>:
        <action>: …

Are you still using Modal dialogs?



Javascript

Progressive Enhancement

  • {:.fragment}opposite of Graceful Degradation
    • {:.fragment}create a functional app without javascript nor styling
    • {:.fragment}add javascript enhancements
    • {:.fragment}add styling
  • {:.fragment} ideal in Rails context

Progressive Enhancement Javascript Example

view

Date:
<span data-transform="localDateTime"><%= @meal.consumption_time.iso8601 %></span>

local_date_time.js

function transformDateToLocal(_, el){
  $el.text(new Date($(el).text().trim()).toLocaleString);
}
function transformDatesToLocal(){
  $('[data-transform="localDateTime"]').each(transformDateToLocal)
}
$(transformDatesToLocal);

Takeaways

  • Minimize altering of HTML source code

      <span data-transform="localDateTime">
    
  • {:.fragment} Do not use id nor class to bind the javascript code, use data-attributes.

    $('[data-transform="localDateTime"]')
valid cases for ids: 1. as anchors to link to topics inside HTML 2. to bind labels to form fields => and even then, we could probably better wrap the fields inside a label ... ids for tests? Bad practice.
  • {:.fragment}Create separate files for separate javascript concerns.


Styling

Semantic classes

View

<form class="meal">
  …

{:.fragment} css file

form.meal{
  …
}

Styling

Semantic classes & bootstrap

(or any other framework)

<button class="btn">

{:.fragment} :skull:


Semantic classes & bootstrap

(or any other framework)

  • {:.fragment}Gemfile

    gem 'bootstrap-sass'
    
  • {:.fragment}Views

    <button>
    
  • {:.fragment}application.scss

    button{ @import .btn; }
    


Accessibility

[](TODO: Bootstrap example)

  1. {:.fragment}Having an app that has proper semantic tags and is usable without css covers already a lot.
  2. {:.fragment}Did you test with a screenreader before and after you add ARIA attributes/roles?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment