View
Linked content

CSS: Using the current text color for other color properties

There is a kinda secret, yet well supported CSS feature called currentColor. It's like a special CSS variable that has been supported in almost all browsers for almost all time (see linked Caniuse).

Usage

The currentColor value can be used in CSS to indicate the current value of color should be used. A common use case is setting a border color:

a.ghost
  color: white
  border: 1px solid currentColor
  &:hover
    color: red // Border color will change as well 

Note that in many cases, you can simply omit the color to ac…

Linked contentRepeats

Lazy-loading images

Since images are magnitudes larger in file size than text (HTML, CSS, Javascript) is, loading the images of a large web page takes a significant amount of the total load time. When your internet connection is good, this is usually not an issue. However, users with limited bandwidth (i.e. on mobile) need to mine their data budget better.

One popular strategy to improve the website performance is to not load images until they enter the viewport – aka "lazy-loading images".

General Issues

  • Crawlers do not execute JavaScript (generally sp…
Repeats

Rails asset pipeline: Why things break in production and what precompilation does to your assets

When you work with a Rails 3.1+ application, you will be working with the asset pipeline. The asset pipeline is awesome until you deploy. Then it will be less so if you haven't done everything as the pipeline expected it from you.

The problem

When using the asset pipeline your assets (images, javascripts, stylesheets, fonts) live in folders inside app:

app/assets/fonts
app/assets/images
app/assets/javascripts
app/assets/stylesheets

With the asset p…

Linked contentRepeats

Fix PNG colors in IE, old Safaris and new Firefoxes

Some browsers render PNG images with color profiles and other shenanigans, some don't. Remove some PNG chunks to render colors uniformly.

Geordi brings a command png-optimize which conveniently optimizes your PNGs for the web. See Github for a description

  • Single file and batch optimization is supported
  • png-optimize will overwrite the original files

Without Geordi

Linux:
sudo apt-get install pngcrush
  • Single file:

    pngcrush -rem...
    
Linked contentRepeats

Carrierwave: Built-in RSpec matchers

CarrierWave comes with some RSpec matchers which will make testing more comfortable. Let's say you have an Uploader like this:

class MyUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  # Create different versions of your uploaded files:
  version :small do
    process resize_to_fill: [100, 100]
  end
  
  version :medium do
    process resize_to_fit: [200, nil]
  end
  
  version :large do
    process resize_to_limit: [400, 400]
  end

end

Imagine you have a class Movie with an attribute poster. In …

Rails: How to provide a public link in a mail

Lets say we have a user with a contract whereas contract is a mounted carrierwave file.

Now we want to send the link to the contract in a mail. For this use case join the root_url with the public contract path in the mailer view:

Plain text email

URI.join(root_url, @user.contract.url)

HTML email

link_to('Show contract', URI.join(root_url, @user.contract.url).to_s)

Note: You need to follow [http://guides.rubyonrails.org/action_mailer_basics.html#g…

How to resize your boot partition when there is an encrypted partition after it

Boot partitions from installations prior to the 16.04 era are terribly small. When you install updates and encounter errors due to a full /boot partition, consider risizing it.

If you can't do the steps described below, ask someone experienced to help you out.
This has worked 100% so far. 1 out of 1 tries. ;)

Scenario A: There is unassigned space on your physical drive

When there is some unpartitioned space on your drive, increasing the size of /boot is actually very easy (even though the list below is rather long). It only takes a…

Repeats

Grep through the DOM using the Capybara API

When your Cucumber feature needs to browse the page HTML, and you are not sure how to express your query as a clever CSS or XPath expression, there is another way: You can use all and find to grep through the DOM and then perform your search in plain Ruby.

Here is an example for this technique:

Then /^I should see an image with the filename...

Chrome: Making high-resolution website screenshots without add-ons

If you want to make a screenshot of a website that works well in print or on a high-DPI screen (like Apple Retina displays), here is how you can capture a high-resolution screenshot.

You can do this without an addon:

  • Open the website
  • If you have multiple monitoros:
    • Resize the Chrome window so it covers multiple monitors (in Linux you can hold ALT and resize by dragging with the right mouse button)
    • Zoom into the page using CTRL + and CTRL - so it covers most of the window area. Leave generous padding on the left and right so…

Capybara: A step for finding images with filename and extension

This cucumber step is useful for testing an image (looking at the src of the image).

Then(/^I should see the image "([^"]*)"$/) do |filename_with_extension|
  expect(page).to have_css("img[src*='#{filename_with_extension}']")
end
Then I should see the image "placeholder.png"

Outline: Read more about how to test a uploaded file here, e.g. file downloads.

Sprites with Compass

Using CSS sprites for background images is a technique for optimizing page load time by combining smaller images into a larger image sprite.

There are ongoing arguments on how useful this still is, as modern browsers become more comfortable to load images in parallel. However, many major websites still use them, for example amazon, [facebook](…

Repeats

Carrierwave: Deleting files outside of forms

TL;DR Use the #remove_<mounted_attribute>! method to delete attachments. Also, save the record after removing the file!


As you know, Carrierwave file attachments work by mounting an Uploader class to an attribute of the model. Though the database field holds the file name as string, calling the attribute will always return the uploader, no matter if a file is attached or not. (Side note: use #present? on the uploader to check if the file exists.)

class User < ApplicationRecord
  mount :avatar, AvatarUploader
end

Repeats

CarrierWave: How to remove GIF animation

When accepting GIF images, you will also accept animated GIFs. Resizing them can be a time-consuming task and will block a Rails worker until the image is processed.

Save yourself that trouble, and simply tell ImageMagick to drop any frames but the first one.

Add the following to your uploader class:

process :remove_animation

private

def remove_animation
  if content_type == 'image/gif'
    manipulate! { |image| image.collapse! }
  end
end

You may also define that process for specific versions only (e….

Linked content

CSS: Giving text lines a background-color (with configurable line padding and margin)

The gist is:

  • wrap the text with a span
  • use line-height for the spacing between lines ("margin")
  • use box-shadow to control the line background size ("padding")

Example

text_lines_with_background_color.png

span
  box-shadow: 0 0 0 10px #fff
  background-color: #fff
  box-decoration-break: clone # Fix Firefox
  line-height: 2.2

→ [jsfiddle](https://jsfiddle.net/2fmqgbh…

Linked contentRepeats

CSS has a well-supported :empty selector

All browsers + IE9 know the CSS :empty selector. It lets you hide an element when it has no content, i.e. not even white space.

For instance, you have a badge displaying the number of unread messages in a red bubble with white text:

.unread-messages-bubble {
  background-color: red;
  border-radius: 10px;
  padding: 10px;
  color: white;
}

To hide that bubble entirely when there are no new messages:

.unread-messages-bubble:empty {
  display: none;
}

Note that the element must be…

Repeats

Async control flow in JavaScript: Promises, Microtasks, async/await

Slides for Henning's talk on Sep 21st 2017.


Understanding sync vs. async control flow

Talking to synchronous (or "blocking") API

print('script start')
html = http_get('/foo')
print(html)
print('script end')

Script outputs 'script start', (long delay), '<html>...</html>', 'script end'.

Talking to asynchronous (or "evented") API

print('script start')
http_get('foo', done: function(html) {
  print(html)
}
print('script end')

Script outputs `'script st…

Spreewald: Content-Disposition not set when testing a download's filename

Precondition

  • You are not using javascript tests
  • The file is served from a public folder (not via controller)

Problem description

If you deliver files from a public folder it might be that the Content-Disposition header is not set. That's why the following spreewald step might raise an error:

Then I should get a download with filename "..."
expected: /filename="some.pdf"$/
     got: nil (using =~) (RSpec::Expectations::ExpectationNotMetError)

Solution

One solution…

Linked content

A Theme Switcher

Hack to implement an inverted "night mode" theme with a few lines of CSS.

Colors in images are preserved.

This website uses cookies to improve usability and analyze traffic.
Accept or learn more