Material design color palette

Bottom line, you can't generate a palette using a single color that will always exactly match the corresponding Google Material Design Palette.

This is because the palettes all follow a different progression of colors. For example, the red palette is generated using the following progression (JS code using TinyColor.js, but you can still see the HSL modifications):

return [
            { hex : tinycolor( hex ).lighten( 37.7 ).saturate( 10.4 ).spin( -13 ).toHexString(), name : '50' },
            { hex : tinycolor( hex ).lighten( 31.8 ).saturate( 10.4 ).spin( -9.5 ).toHexString(), name : '100' },
            { hex : tinycolor( hex ).lighten( 18.7 ).desaturate( 17 ).spin( -3.9 ).toHexString(), name : '200' },
            { hex : tinycolor( hex ).lighten( 9.1 ).desaturate( 20.9 ).spin( -4 ).toHexString(), name : '300' },
            { hex : tinycolor( hex ).lighten( 4.1 ).desaturate( 6.6 ).spin( -3 ).toHexString(), name : '400' },
            { hex : hex, name : '500' },
            { hex : tinycolor( hex ).darken( 3.1 ).desaturate( 12.4 ).spin( -2.7 ).toHexString(), name: '600' },
            { hex : tinycolor( hex ).darken( 7.8 ).desaturate( 24.5 ).spin( -4 ).toHexString(), name: '700' },
            { hex : tinycolor( hex ).darken( 11.7 ).desaturate( 23.2 ).spin( -4 ).toHexString(), name: '800' },
            { hex : tinycolor( hex ).darken( 17 ).desaturate( 16.1 ).spin( -4 ).toHexString(), name: '900' },
            { hex : tinycolor( hex ).lighten( 16.7 ).saturate( 10.4 ).spin( 0.6 ).toHexString(), name: 'A100' },
            { hex : tinycolor( hex ).lighten( 7.7 ).saturate( 10.4 ).spin( -4 ).toHexString(), name: 'A200' },
            { hex : tinycolor( hex ).darken( 3.9 ).saturate( 10.4 ).spin( -15.5 ).toHexString(), name: 'A400' },
            { hex : tinycolor( hex ).darken( 16.6 ).saturate( 10.4 ).spin( -4 ).toHexString(), name: 'A700' }
        ];

However, when you apply that same progression to the Indigo base color (500), you can see that the palettes don't match up at all. In the following image, the far left palette is the default MD pallette and the second to the left is the palette generated with the above progression. These two palettes match exactly. When I load in the MD Indigo palette (third palette) and then generate a palette using the Indigo 500 value and the Red Palette progression code, it creates the 4th palette. As you can see, while this progression is exact for red, it's way, way off for other colors:

enter image description here

More on this subject can be found here. It's most likely that the colors google has chosen are hand-picked by a designer and not programmatically generated.

EDIT: Also, the code for that MCG has been completely revised. The new logic for the colors can be found here, and it uses tinycolor.js for the modification functions.


The logic in the accepted answer is wrong. It won't generate the true material colours for you. There is an official material palette tool here. You can try and compare if you want.

Unfortunately there is no library provided from Google for the above tool, this is a minified and packed javascript file which includes redux inside. Me and my colleague, we did a reverse engineering to get the part that generates the colours only, you can view it here. Please keep in mind that this is not my code.

you can try it here with the following line.

materialColorPicker('00ff00')

This palette has different tones of the selected colour, these are: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900 but the given colour could be any of these tones.

for example, if you pick red colour, this palette will give you the following set.

50: "ffe7e6"
100: "ffc7b8"
200: "ffa28a"
300: "ff795b"
400: "ff5436"
500: "ff200c"
600: "ff1507"
700: "ff0000" // input colour
800: "f10000"
900: "da0000" 

But if you pick the colour of #17996b, the palette will produce the following values:

50: "e0f3ec"
100: "b4e0cf"
200: "84cdb1"
300: "54b893"
400: "32a97f"
500: "17996b" // input colour
600: "138c60"
700: "0d7c52"
800: "016c45"
900: "00502a"

As you see, the input colour which you think it's your primary colour, can be any of the produced colours.