Linked content

How to exploit websites that include user input in their CSS

The linked article shows how to exploit websites that include unsanitized user input in their CSS.

Although the article often mentions React and CSS-in-JS libraries, the methods are applicable to any web app that injects user input into style tags or properties.

Also, sanitizing user input for CSS injection is much harder than sanitizing HTML.

Linked content

A Theme Switcher

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

Colors in images are preserved.

Linked content

Know what makes your browser pant

I figure we needed a definitive reference for what work is triggered by changing various CSS properties. It's something I get asked about often enough by developers, and while we can do tests with DevTools, I have both the time and inclination to shortcut that for everyone. I'm nice like that. —Paul Lewis

Cucumber: Test that an element is not overshadowed by another element

I needed to make sure that an element is visible and not overshadowed by an element that has a higher z-index (like a modal overlay).

Here is the step I wanted:

Then the very important notice should not be overshadowed by another element

This is the step definition:

Then(/^(.*?) should not be overshadowed by another element$/) do |locator|
  selector = selector_for(locator)
  expect(page).to have_css(selector)
  js = <<-JS
    var selector = #{selector.to_json};
    var elementFromSelector = document.querySelector(selector)...

How to define height of a div as percentage of its variable width

This is useful if, for example, you want to use a background-image that has to scale with the width and the div should only have the height of the picture.


<div class="outer">
  <div class="inner">


.outer {
  width: 100%;
  background-image: image-url('background.png');
  background-size: cover;
.inner {
  padding-top: 60%;

How does it work?

There are several CSS attributes that can handle values as percentage. But they use different other attributes as "reference value...

Middleman for Rails Developers

Middleman is a static page generator that brings many of the goodies that Rails developers are used to.

Out of the box, Middleman brings Haml, Sass, helpers etc. However, it can be configured to do even better. This card is a list of improvement hints for a Rails developer.


Remove tzinfo-data and wdm unless you're on Windows. Add these gems:

gem 'middleman-livereload'
gem 'middleman-sprockets' # Asset pipeline!

gem 'bootstrap-sass' # If you want to use Bootstrap

gem 'byebug'

gem 'capistrano'
gem 'capistrano-mid...
Linked content

Classic CSS problems that are easy with flexbox

Solved with flexbox is a collection of css problems which were hard or impossible to solve without flexbox:

  • Better, Simpler Grid Systems
  • Holy Grail Layout
  • Input Add-ons
  • Media Object
  • Sticky Footer
  • Vertical Centering
Linked content

image-to-DataURI converter:

Small web application where you can upload an image (PNG, JPEG, GIF) and generate a base64-encoded version of it.

You can copy the result as

  • HTML <img> tag with data URI,
  • CSS rule with background-image and data URI,
  • plain Base64-encoded data URI string.
Linked content

iOS Safari scales text in landscape mode

iOS Safari tries to be helpful and enlarges some(!) texts when you turn to landscape mode. In precise CSS building, this is annoying. Disable this behavior with:

  -webkit-text-size-adjust: 100% // Prevent font scaling in iOS landscape

Beware: Nested Spreewald patiently blocks are not patient

Note: The behaviour of Spreewald's within step is as described below for version < 1.9.0; For Spreewald >= 1.9.0 it is as described in Solution 1.

When doing integration testing with cucumber and selenium you will often encounter problems with timing - For example if your test runs faster than your application, html elements may not yet be visible when the test looks for them. That's why Spreewald (a collection of cucumber steps) has a concept of doing things patiently, which means a given b...

SASS: Defining linear sizes

Just dumping this in case somebody might need it.

When you need a CSS value (a padding, margin, height etc) to shrink/grow proportionally with the parent element, you normally use percentage values. However, if you need specific values at two given widths, you need to turn to linear functions. The mixin below gives you just that.

// Call with two desired values at two different widths.
// Returns a calc() expression that will scale proportionally between those two.
// Example:
//   Spaci...
Linked content

CSS tests and experiments

The pages listed here contain tests and experiments about features, possibilities, browsers’ bugs concerning CSS.

That is, over 200 experiments.

Sass: Don't put CSS rules into partials that you import multiple times

TLDR: When you put CSS rules into a partial and import that partial multiple times, the CSS rules will be duplicated in the compiled CSS.

Here is a Sass partial called _fonts.sass that contains both CSS rules and a mixin:

  font-family: SuperType
  src: url('supertype.woff')
  font-family: SuperType

This _fonts.sass is not practical in CSS projects that are organized over multiple files: When you...

Linked content

An Introduction to Sending HTML Email for Web Developers

A comprehensive introduction to sending HTML emails.


HTML email: Two words that, when combined, brings tears to a developer’s eyes. If you’re a web developer, it’s inevitable that coding an email will be a task that gets dropped in your lap at some time in your career, whether you like it or not. Coding HTML email is old school. Think back to 1999, when we called ourselves “webmasters” and used Frontpage, WYSIWYG editors and tables to mark up our websites.

Table of Contents

  • Introduction To Sending Email Link
  • Email List B...
Linked content

Angular: Quick and easy animation on changed binding value

With ngAnimate, you can easily animate certain events (see directive support). We'll make use of ngClass animations to style an element on changed binding value.

Say we have a slider and a separate details container. Each time the slider changes, we want to "flash" the details container by hiding it and fading it back in.


Add a custom class to the element you want to animate, i.e. the details container:

<div class="details slide-index-{{ currentSlideIndex }}">
  {{ co...
Linked content

A case for different breakpoints

The linked article states that CSS breakpoints should group "similar" screen sizes and thus be at:

  • 600px "narrow"
  • 900px "medium"
  • 1200px "wide"
  • (1800px) "huge"

By choosing these breakpoints, most device screens will be somewhere between two breakpoints, and not at the very edge of them.

The ranges could be called:

  • narrow (< narrow)
  • medium (narrow - medium)
  • normal (medium - wide)
  • wide (wide - huge)
  • huge (> huge)

Styling SVGs with CSS only works in certain conditions

SVG is an acronym for "scalable vector graphics". SVGs should be used whenever an image can be described with vector instructions like "draw a line there" or "fill that space" (they're not suited for photographs and the like). Benefits are the MUCH smaller file size and the crisp and sharp rendering at any scale.

It's a simple, old concept brought to the web – half-heartedly. While actually all browsers pretend to support SVG, some barely complex use cases get you beyond common browser support.

In the bas...

Sass: How to do math with shorthand values inside variables

If you need to modify (e.g. add 2px) a Sass variable that defines multiple values as one (e.g. for short-hand CSS definitions such ass padding), you can by using nth. It's ugly.

While you could split up such variables into multiple values (e.g. combined padding into one for vertical and one for horizontal padding) in your own Sass definitions, when using some framework definitions like bootstrap-sass, those variables are defined outside your reach.

The following is helpful if you really want to use values from such variables. However...

This website uses short-lived cookies to improve usability.
Accept or learn more