Sass Mixins vs Extends: The Data - Belly Card Engineering

The debate between using mixins or extends in Sass has been heating up recently. From the surface it appears they both provide solid benefits in helping us write consistent and modular code. However, the critics are out and extends specifically have come under fire. But why?

Interesting results: Although mixins create more code than extends, the gzipped CSS is smaller and somewhat faster to evaluate for current browsers.

An auto-mapper for BEM classes in Cucumber selectors

When you are using the #selector_for helper in Cucumber steps, as e.g. Spreewald does, the following snippet will save you typing. It recognizes a prose BEM-style selector and maps it to the corresponding BEM class.

For a variation on this idea, see An auto-mapper for ARIA labels and BEM classes in Cucumber selectors.

Examples

"the main menu" -> '.main-menu'
"the item box's header" -> '.item-box--header'

Here are some examples of steps (using Spreewald, too):

T...

Understanding z-index: it's about stacking contexts

The CSS property z-index is not as global as you might think. Actually, it is scoped to a so-called "stacking context". z-indexes only have meaning within their stacking context, while stacking contexts are treated as a single unit in their parent stacking context. This means indices like 99999 should never actually be needed.

Creating a new stacking context

In order to create a stacking context with the least possible side effects, use the isolation property on an...

Rendering: repaint, reflow/relayout, restyle

Some insight into how browser rendering engines work. The article shows how the way you manipulate styles (and the DOM) can affect rendering performance by forcing the browser to re-paint large portions of the screens, or re-calculate the dimensions of a large subtree of DOM nodes.

flag-icon-css: Scalable country flags

Use it like this for inline icons:

<span class="flag-icon flag-icon-de"></span> Germany

They also work as block elements:

<div class="flag-wrapper">
  <div class="flag flag-icon-background flag-icon-de"></div>
</div>

Jasmine: Testing AJAX calls that manipulate the DOM

Here is a Javascript function reloadUsers() that fetches a HTML snippet from the server using AJAX and replaces the current .users container in the DOM:

window.reloadUsers = ->
  $.get('/users').then (html) ->
    $('.users').html(html)

Testing this simple function poses a number of challenges:

  • It only works if there is a <div class="users">...</div> container in the current DOM. Obviously the Jasmine spec runner has no such container.
  • The code requests /users and we want to prevent network interaction in our uni...

velesin/jasmine-jquery

This jasmine plugin helps with testing DOM manipulation in two ways:

  1. It gives you DOM-related matchers like toBeVisible() or toHaveCss(css)
  2. It gives you a function to load HTML from fixture files. Without this you would have to manually add elements to <body> and clean up afterwards.

AngularJS: Binding to Perl-style getter/setters functions

Angular 1.3+ has an alternative getter/setter pattern: You can bind ng-model to an accessor function. This is a function that is either a getter (when it gets no arguments) or a setter (when it gets the new value as an argument):

$scope.name = function(newName) {
  return angular.isDefined(newName) ? (_name = newName) : _name;
}

You need to bind this function with ng-model and `ng-model-options="{ getterSette...

Make jQuery.animate run smoother with almost no code changes

jQuery comes with .animate() that lets you transition some CSS selectors:

function floatIn($element) {
  $element.css({ 'opacity': 0, 'margin-top': 200px });
  $element.animate({ 'opacity': 1, 'margin-top': 0 }, { duration: 500 });
}

The animation is implemented using setInterval and Javascript. This works great, but it's not as smooth as a CSS transition.

Fortunately the animate API can be mapped almo...

thoughtbot/bourbon

Bourbon is a library of pure Sass mixins that are designed to be simple and easy to use. No configuration required. The mixins aim to be as vanilla as possible, meaning they should be as close to the original CSS syntax as possible.

The mixins contain vendor specific prefixes for all CSS3 properties for support amongst modern browsers. The prefixes also ensure graceful degradation for older browsers that support only CSS3 prefixed properties.

Managing vendor libraries with the Rails asset pipeline

The benefit of the Rails asset pipeline is that it compiles your stylesheets and javascripts to a single file, respectively. However, the consequences are startling if you don't understand them. Among others, the raw asset pipeline requires you to have all your asset libraries in the same folder, which quickly becomes confusing as your set of assets grows. To overcome this, we have two different solutions.

Custom solution

We are using a custom workaround to keep library files apart in their own directories. To avoid b...

Asset Pipeline Basics

The Rails asset pipeline improves delivery of application assets (javascripts, stylesheets, images, fonts). Here are some basic facts about its inner workings.

No magic

Manifests are the handle on your assets:

app/assets/stylesheets/application.css # use via: stylesheet_link_tag 'application'

The asset pipeline only considers files you explicitly require within your manifest files. The most common directives used in manifests are require some/file and require_tree some/directory. Paths may be **relative to the current director...

josephschmitt/Clamp.js

Clamps (ie. cuts off) an HTML element's content by adding ellipsis to it if the content inside is too long.

While you can only truncate single lines with CSS by using text-overflow, this small JavaScript library also allows truncating text after multiple lines.

Please note:

  • For Internet Explorer, the element you clamp on needs to have its line-height set in pixels. A relative value will not work.
  • There is also the [-webkit-line-clamp](http:...

Bootstrap: How to avoid printing link URLs

By default, Twitter Bootstrap's print styles include printing links.

/* Bootstrap's way of printing URLs */
@media print {
  a[href]:after {
    content: " (" attr(href) ")";
  }
}

If you want to turn that off, you can do

/* Don't print link hrefs */
@media print {
  a[href]:after {
    content: none
  }
}

Prevent LibreOffice from changing standard styles when you format individual characters

You select some characters, make them bold and suddenly your entire document is bold?

Here's how to fix that:

  • Right-click the style in the "Styles and Formatting" window
  • Select "Modify"
  • Go to the "Organizer" tab
  • Unselect "AutoUpdate"

You're welcome.

bower-rails can rewrite your relative asset paths

The asset pipeline changes the paths of CSS files during precompilation. This opens a world of pain when CSS files reference images (like jQuery UI) or fonts (like webfont kits from Font Squirrel), since all those url(images/icon.png) will now point to a broken path.

In the past we have been using the vendor/asset-libs folder ...

When Sass-generated stylesheets print a Encoding::CompatibilityError

We upgraded a Rails 2 application to Rails 3.2 and Ruby 2.1, changed the mysql adapter from mysql to mysql2, but did not activitate the asset pipeline. Instead we used Sass the old-school way (stylesheets in public/sass/*.sass) and relied on stylesheet_link_tag to activate the Sass compiler.

Now all Sass-generated stylesheets inserted the following text into body:before:

Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT

I could get rid of this by removing all generated .css files in `...

What we know about PDFKit

What PDFKit is

  • PDFKit converts a web page to a PDF document. It uses a Webkit engine under the hood.
  • For you as a web developer this means you can keep using the technology you are familar with and don't need to learn LaTeX. All you need is a pretty print-stylesheet.

How to use it from your Rails application

  • You can have PDFKit render a website by simply calling PDFKit.new('http://google.com').to_file('google.pdf'). You can then send the...

Transactional HTML Email Templates

Styling HTML email is painful. Tables, inline CSS, unsupported CSS, desktop clients, web clients, mobile clients, various devices, various providers. All these things have to be thought about and tested. It’s no surprise developers don’t want to deal with this when there is a backlog of more important priorities.

We’ve tried to remove some of the pain for you and open-sourced a collection of common templates for transactional email.

Alternative transactional email templates include

  • [these ones...](https://www.sendwithus.com/resource...

Vertical align anything with just 3 lines of CSS

See attached link. The gist is:

.element {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}

Works in all web browsers and IE9+.

Sass partial names must always start with an underscore

Be careful to name any file @imported by SASS with a leading underscore.

SASS files not beginning with an underscore will be rendered on their own, which will fail if they are using variables or mixins defined elsewhere. (For me it broke only in production, which may be due to some settings in SASS-GEM/lib/sass/plugin/rails.rb.)

From the SASS docs:

The underscore lets Sass know that the file is only a partial file and that it should not be generated into a CSS file.

SudoSlider: a jQuery slider

SudoSlider is a simple yet powerful content slider that makes no (or very few) assumptions about your markup and is very customizable.

You can basically embed any HTML into the slides, so you can mix images, videos, texts, and other stuff.

Check out the demos.

Please note:

  • There is a ton to configure. Check the demos and read the docs.
  • It does not bring styles for prev/next links etc, so you need to style controls yourself (which I consider to b...

Cucumber step to manually trigger javascript events in Selenium scenarios (using jQuery)

When you cannot make Selenium trigger events you rely on (e.g. a "change" event when filling in a form field), trigger it yourself using this step:

When /^I manually trigger a (".*?") event on (".*?")$/ do |event, selector|
  page.execute_script("jQuery(#{selector}).trigger(#{event})")
end

Note that this only triggers events that were registered through jQuery. Events registered through CSS or the native Javascript registry will not trigger.

Get the last leaf of a DOM tree (while considering text nodes)

I use this to simulate the (non-existing) :last-letter CSS pseudoclass, e. g. to insert a tombstone at the end of an article:

findLastLeaf = ($container) ->
  $children = $container.children()
  if $children.length == 0
    $container
  else
    $lastChild = $children.last()
    $lastContent = $container.contents().filter(->
      # Only return nodes that are either elements or non-empty text nodes
      @nodeType == 1 || (@nodeType == 3 && _.strip(@nodeValue) != '')
    ).last()
...