Speaker at Symfony Live Cologne 2016

I am happy to announce that i will speaking at Symfony Live Cologne 2016 end of April.

This conference is a german speaking conference, so my talk will be in german but i will prepare all slides in english.

After writing and talking about Project Ironman which was a lot of fun, i will this time focus more on the integration of a Pattern Library in a high performance Symfony application.

By the beginning of 2015 we started building up a Pattern Library, and did a lot a technical adaptions to it, some of them to adapt it to our needs and others to work forward to a smoothless integration into our core product at trivago, the hotel search.

I give will insights on the development of the Pattern Library, the design and business related requirements and technical approaches to integrate it into different appliations.

You can find the Conference schedule here

Week of the referrals

Promoted by Smashing Magazine. Not the worst thing that can happen.

After posting about our CSS refactoring  project at trivago on different platforms i have received a lot of feedback, tweets and mails which made me and the whole project team very happy. We worked hard on this project and we are proud about the results and the way we solved this challenge. Apparently we hit the spirit of the times which we didn’t expect in that way. Taming CSS complexity in large scale applications is a topic which are many people interested in.

What made the blog post so interesting was obviously the concrete reference to a real life project. 


Browser support & fallbacks for CSS

Not all browser provide the same capabilities e.g. in support of some (newer) CSS features. In case we want to use a CSS feature with limited support, it is our responsibility as developers to provide a good fallback so that users with a browser that supports the feature can actually enjoy it, while the users which browser doesn’t support a feature will still be able to access our content in a similar way.

The most excellent site i am aware of is caniuse.com which provides you detailed information about browser support of a feature. Sometimes you might find that a certain feature is supported, but slightly different across browsers. For example it might need a vendor prefix, or slightly different syntax. You can almost use different syntaxes alongside and let the cascade take care of which one wins. For this reason, always place the standard version last. For example to apply box-sizing as a border-box value you might need to introduce a vendor prefix to support e.g. Android 2.3 devices.

.box {
-webkit-box-shadow: 0px 1px 4px rgba(0,0,0,0.2);
box-shadow: 0px 1px 4px rgba(0,0,0,0.2);

Every browser supporting the unprefixed version will use box-shadow while the android 2.3 stock browser will use the prefixed version because it has no implementation of the unprefixed version.

Most of the time it’s a good practice to provide fallbacks, so that your site doesn’t break in older browsers, even if it doesn’t look as fancy in them (Do websites need to look the same in very browser?)

Lets take as an example a linear background. If you know how the cascade works implementing a fallback is very easy (due to the fact that CSS is so fault tolerant and everything is just ignored what a browser does not understand).

If you want to use a linear gradient from yellow to red, you might to apply the average of the two gradient colors first before defining the linear-gradient. So in case the browser does not support it, it will stick to the rgb() value otherwise it will apply one of the following declarations:

.selector {
background: rgb(255,128,0);
background: -moz-linear-gradient(0deg, yellow, red);
background: -webkit-linear-gradient(0deg, yellow, red);
background: linear-gradient(90deg, yellow, red);

However, sometimes it is not possible to provide decent fallbacks through the cascade. As a last resort you could use tools like modernizr, which adds classes like csstransforms or no-csstransforms to the root element, so you can use them to target elements only when certain features are supported, like e.g.:

.my-headline {
color: #333;
.textshadow .my-headline {
color: transparent;
text-shadow: 0 0 2px #333;

if the feature you are trying to create a fallback for is sufficiently new, you could also use the @supports rule, which is the native modernizr. For example the CSS grid specification might me a good use case for this.

.my-element:before {
content: "does not support css grid";
@supports (display: grid) {
.my-element:before {
content: "supports css grid";

However, for now be wary of using @supports. By using it we limit our effort not only to browser that support the CSS grid, but also to browser that support the @supports rule. Maybe a more limited set.

Last but not least there is always the choice of using a few lines of home-baked Javascript to perform feature detection in the same fashion as a feature detection library. The main way to determine whether a property is supported is to check its existence on the element.style object of any element. An incomplete example for flexbox support might look like this:

var docRoot = document.documentElement; //html-node
if ('flexBasis' in docRoot.style) {
else {

If we want to test for a value, we need to assign it to the property and check if the browser retains it. Because we are modifying styles here and not just testing for their existence, it makes sense to use a dummy element:

var docRoot = document.documentElement;
var dummy = document.createElement('p');
dummy.style.backgroundImage = 'linear-gradient(blue,yellow)';
if (dummy.style.backgroundImage) {
else {

Of course if you want to test for multiple features both should be converted to a function.
Testing selectors and @rules is a more complicated, but follows the same principle: when it comes to CSS, browser drop anything they don’t understand, so we are able to check if a feature is recognized by applying it and checking if it was retained.

Keep in mind that even if a browser is able to parse a CSS feature this does not mean that the feature is correctly implemented, or even implemented at all.

Blog-Posts about Project Ironman

As announced in my last post i finally wrote my article about Project Ironman for my companies tech-blog. You can find the post here or on Medium.

I received a lot of (nice) feedback mostly via twitter.