CSS Grid Display allows defining number of grid columns based on child width

An element with display: grid can define its grid-template-columns based on (preferred) child width using the repeat function with auto-fill or auto-fit, like so:

grid-template-columns: repeat(auto-fit, 100px)

auto-fill and auto-fit behave differently if you use rules with dynamic sizing, like minmax(100px, 1fr). Simply put, auto-fill will create as many columns as possible, including empty ones, while auto-fit hides empty columns.

See the linked page for more details.

Defensive CSS

Table Of Contents

  • Flexbox wrapping
  • Spacing
  • Long content
  • Prevent an image from being stretched or compressed
  • Lock scroll chaining
  • CSS variable fallback
  • Using fixed width or height
    • The fixed height
    • The fixed width
  • Forgetting background-repeat
  • Vertical media queries
  • Using justify-content: space-between
  • Text over images
  • Be careful with fixed values in a CSS grid
  • Show a scrollbar only when it's needed
  • Scrollbar gutter
  • Minimum content size in CSS flexbox
  • Minimum content size in CSS grid
  • Auto fit vs auto...

Selector for finding the currently selected option in a <select> tag

Use option:checked to find the currently selected option:

select.querySelector('option:checked')

Yes, :checked, not :selected.

This is the same as finding an option with the { selected: true } property in JavaScript:

select.querySelectorAll('option').find((option) => option.selected)

What about the selected attribute?

Note that option[selected] would only find an <option selected> tag. This may be the selected option right after loading the page, but not once the user switched to a different value. ...

RSpec: How to aggregate failures

RSpec >= 3.3 added aggregate_failures, which allows multiple failures in an example and list them all, rather than aborting on the first failure.

This can be used:

  • In the global configuration
  • With the tag :aggregate_failures (our preferred option in case every expectations should be aggregated)
  • With the method aggregate_failures

[Here](https://web.archive.org/web/20210110131654/https://relishapp.com/rspec...

Jasmine: Spy on value properties

Jasmine has spyOnProperty(), but it only works if the property is implemented using getter and setter functions. This is a known limitation of Jasmine.

If the mocked property is a simple value, it will not work:

const x = { foo: 1 }
console.log(x.foo) // 1
spyOnProperty(x, 'foo').and.returnValue(2)
// Throws: Error: <spyOnProperty> : Property foo does not have access type get

Below you can find a function `spyOnValuePr...

Nokogiri: How to parse large XML files with a SAX parser

In my case [...] the catalog is an XML that contains all kinds of possible products, categories and vendors and it is updated once a month. When you read this file with the Nokogiri default (DOM) parser, it creates a tree structure with all branches and leaves. It allows you to easily navigate through it via css/xpath selectors.

The only problem is that if you read the whole file into memory, it takes a significant amount of RAM. It is really ineffective to pay for a server if you need this RAM once a month. Since I don't need to n...

New gem: Rack::SteadyETag

Rack::SteadyETag is a Rack middleware that generates the same default ETag for responses that only differ in CSRF tokens or CSP nonces.

By default Rails uses Rack::ETag to generate ETag headers by hashing the response body. In theory this would enable caching for multiple requests to the same resourc...

Spreewald 4.3.3 released

Field error steps

Spreewald's The ... field should have an error and The ... field should have the error ... steps now have built-in support for Rails and Bootstrap (v3-v5) error classes. When using Bootstrap, it is no longer necessary to overwrite the steps in your project.

At the same time, support for formtastic has been removed as there were no real use cases. Due to that, no breaking change was introduced, as the amount of users affected by this should be zero (it was neither in the documentation nor tested).

Users may now add...

Semantic HTML

Besides their default styling properties, HTML elements have a semantic meaning. For example, an h1 tag is usually styled with a larger font and bold, while it denotes "the single most important headline in its context".

While CSS enables us to style almost any HTML element like anything that is needed, choosing HTML elements corresponding to the meaning of their content has a few advantages:

  • HTML becomes a little clearer
  • Edge cases have already been considered and implemented:
    • Keyboard support (tabbing, arrow keys)
    • State...

Elasticsearch: recover from readonly mode

Elasticsearch defaults to go into readonly mode when you run low on disk space (< 95%). You might then see an error like this when you try to write to elastic:

Elasticsearch::Transport::Transport::Errors::Forbidden:
       [403] {"error":{"root_cause":[{"type":"cluster_block_exception","reason":"blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];"}],"type":"cluster_block_exception","reason":"blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];"},"status":403}

Even after freeing up space and restarting elas...

JavaScript: Sharing content with the native share dialog

Mobile Chrome and Safari support the "web share API" which allow you to use the native share functionality of an Android or iOS phone. Some desktop OSs like Windows or MacOS also support native share dialogs. See Can I Use for a detailed support matrix.

When clicking a share button using this API, the browser will automatically show all installed applications that support content sharing, such as Whatsapp, Facebook, Twitter, e-mail etc.

The API is extremely simple to use:

if ...

Events triggered by jQuery cannot be observed by native event listeners

jQuery has a function $.fn.trigger(). You can use it to dispatch an event on a jQuery object:

let $element = $('.foo')
$element.trigger('change')

A caveat is that such an event will be received by jQuery event listeners, but not by native event listeners:

let $element = $('.foo')

$element.on('change', event => console.log('I will be called'))
$element[0].addEventListener('change', event => console.log("I WON'T be called"))

$element.trigger('change')

This is not an issue when your entire app is ...

How to reload a belongs_to association

To reload a single-item association in Rails 5+, call #reload_<association>:

post.reload_author

In older Railses you can say

post.author(true)

Ruby: How to use prepend for cleaner monkey patches

Let's say you have a gem which has the following module:

module SuperClient

  def self.foo
    'Foo'
  end
  
  def bar
    'Bar'
  end

end

For reasons you need to override foo and bar.

Keep in mind: Your code quality is getting worse with with each prepend (other developers are not happy to find many library extensions). Try to avoid it if possible.

  1. Add a lib/ext/super_client.rb to your project (see How to organize monkey patches in Ruby on Rails projects)
  2. Add the extension, which ov...

ImageMagick: Converting SVG to raster image formats like PNG or JPEG

Conversion

ImageMagick can convert SVGs to raster image formats.

Example for PNG:

convert input.svg output.png

If the SVG has a size of 24x24 (viewBox="0 0 24 24"), the resulting PNG will also have a size of 24x24.

Resizing

An SVG's viewBox specifies the intended size, but vector image formats can be scaled freely.

Resize flag (poor results)

If you want your raster image to be larger, the naive approach would be to use the resize flag.

convert -resize 96x96 input.svg output.png

However, this resu...

The TCF 2.0 (Tranparency and Consent Framework) standard, and what you should know about it

The Interactive Advertising Bureau (IAB) is a European marketing association which has introduced a standard how advertising can be served to users in line with the General Data Protection Regulation (GDPR). This standard is called the TCF 2.0 (Transparency and Consent Framework). If you want to integrate any kind of advertising into a website, chances are the advertising network will require your website to implement that standard. This is a very brief overview of what this means:

The basic idea in the TCF 2.0 ...

Ad blockers: How to debug blocked elements

Some users might use Adblock Plus or similar browser plugins to reduce the number of ads displayed. If you run into an issue that your application or part of an application is blocked, this card will give you some guidance on how to debug it.


In general ad blocking is not an issue for most of our web apps. But if your application uses iframes or is embedded in another site it's more prone to it.

Blocked elements most of the time appear to the user as empty frames in the page. The indicator icon of the ad blocker also gives ...

vagrant < 2.2.9: handle conflicting host only adapter

I sometimes had the issue that I received an error when starting an existing vagrant box with vagrant up:

A host only network interface you're attempting to configure via DHCP
already has a conflicting host only adapter with DHCP enabled. The
DHCP on this adapter is incompatible with the DHCP settings. Two
host only network interfaces are not allowed to overlap, and each
host only network interface can have only one DHCP server. Please
reconfigure your host only network or remove the virtual machine
using the other host only networ...

Google Chrome now has a JavaScript bundle visualizer

Similar to the Webpack Bundle Analyzer, Chrome's new Lighthouse feature …

… shows a visualisation of your JavaScript bundles. It's compatible with sourcemaps and is great for understanding large JavaScript modules used by your page. It can also visualise unused bytes.

This is very helpful to visualize Javascript files in development. It also works on production code, where its usefulness depends on the structure of the productive Javascr...

no passenger served applications running error when deploying via capistrano

When deploying with capistrano it's possible you get this "error" message:

*** [err :: example.com] There are no Phusion Passenger-served applications running whose paths begin with '/var/www/example.com'.
*** [err :: example.com] 

This is just because there were no running passenger process for this application on the server which could be restarted. It's not a real error. The application process will start if the first request for this app hits the appserver.

The output appears as err because it's printed to stderr.

Dep...

Finding ancestors with Capybara

Modern versions of Capybara include a finder method #ancestor which allows you to find a parental element using CSS or XPath.

If you previously did something like this:

field.find(:xpath, './ancestor::div[contains(@class, "form-group")]')

..and prefer CSS, you may rewrite it:

field.ancestor('div.form-group')

Both versions will return the outermost matching element. Use the #order option find the closest parent:

field.ancestor('div.form-group', order: :reverse)

Hints for debugging MySQL InnoDB deadlocks

Deadlocks only occur if two transactions in separate threads compete for the same rows in the database. They usually (but not necessarily) only happen when trying to update or otherwise lock several rows in different order.

Solving deadlocks is potentially complicated, so here are a few pointers:

  • MySQL should always detect the deadlock right when it happens, and will throw an error to one of the offending threads. This error states the SQL statement that this thread was currently waiting for, and that tried to acquire one of the competin...

You can use graphs in gitlab comments!

Since GitLab 10.3. you can use Mermaid in GitLab comments: Gitlab Doc.
With Mermaid you can create diagrams based on text / code.

Sometimes a picture says more than thousand words and can help you express your thoughts more clearly.

Image

Image

Some Examples from the Mermaid documentation:

Flowcharts

graph TD;
    A-->B;
    A-->C...

Strict Loading Associations can prevent n+1 queries

Rails 6.1 has a "strict loading" mode that forces the developer to preload any association they plan to use. Associations no longer load lazily. An error is raised when reading an association that was not preloaded.

Enabling strict loading is a tool to prevent n+1 queries.

Strict loading can be enabled for individual records, for a single association,...