Li Haoyi
Li Haoyi

Reputation: 15802

CSS hexadecimal RGBA?

I know you can write ...

background-color: #ff0000;

... if you want something that is red.

And you can write ...

background-color: rgba(255, 0, 0, 0.5);

... if you want something red and translucent.

Is there any terse way of writing partially transparent colors in hexadecimal? I want something like:

background-color: #ff000088; <--- the 88 is the alpha

... or ...

background-color: #ff0000 50%;

I am getting all my colors in hexadecimal, and having to convert them all to the decimal 0-255 scale is annoying.

Upvotes: 326

Views: 399486

Answers (17)

Tigerrrrr
Tigerrrrr

Reputation: 1344

The following two modern solutions both work with variables:

Since July 2024

Relative RGB colours, it's pretty cool, you should check it out. But what's important for this solution isn't the new feature itself but the syntax for it!

rgb(from <color> R G B [/ A])

You see that? That <color> means we can now use variables, like: rgb(from var(--secondary-colour) r g b / 0.75);

It also means, you can add opacity to your hexadecimals, without having to try to convert 00-FF to 00-255, e.g; rgb(from #FF0000 r g b / 75%); (a.k.a. #FF0000BF).

A couple of things to note: If you for some reason wanted to use hexadecimals (e.g; BF) to set your opacity... you still can't do that and a similar syntax update has also occurred for: color(), hsl(), hwb(), lab(), lch(), oklab(), and oklch().

It seems to do everything the last method did, so why is it better? Because it's more dedicated, and thus likely more performant (untested). Instead of taking two colours, blending them together and figuring out what the output is, it just generates the "output" colour directly. It also requires fewer characters to type. Oh and... "newer is always better".

Here's a working demo:

span {
  display: flex;
  gap: 4px;
}

div {
  height: 64px;
  width: 64px;
  background: blue;
  
  &:nth-last-child(5) { background: rgb(from blue r g b / 0%); }
  &:nth-last-child(4) { background: rgb(from blue r g b / 25%); }
  &:nth-last-child(3) { background: rgb(from blue r g b / 50%); }
  &:nth-last-child(2) { background: rgb(from blue r g b / 75%); }
  &:nth-last-child(1) { background: rgb(from blue r g b / 100%); }
}
<span>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</span>

Since May 2023 [Superseded]

The best method is to use the relatively new color-mix() function:

div:nth-child(4) {
  background: color-mix(in srgb, blue, transparent 50%);
}

Here's a working demo:

span {
  display: flex;
  gap: 4px;
}

div {
  height: 64px;
  width: 64px;
  background: blue;
  
  &:nth-last-child(5) { background: color-mix(in srgb, blue, transparent 100%) }
  &:nth-last-child(4) { background: color-mix(in srgb, blue, transparent 75%) }
  &:nth-last-child(3) { background: color-mix(in srgb, blue, transparent 50%) }
  &:nth-last-child(2) { background: color-mix(in srgb, blue, transparent 25%) }
  &:nth-last-child(1) { background: color-mix(in srgb, blue, transparent 0%) }
}
<span>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</span>

Why use this method?

This is useful because we can now use CSS variables straight from our design tokens and it also prevents us from having to convert our opacity percentage values into hex, which is great because "75%" or even "0.75" is just a lot more understandable than "BF".

The only issue with this is if you actually wanted to use hex values like "BF" - you can't do that.

Example Scenario: "I'm using design tokens"

:root {
    --primary-colour: teal;
    --opacity-high: 0.75;
}

div {
    background-color: color-mix(in srgb, var(--primary-colour), transparent calc((1 - var(--opacity-high)) * 100%));
}

Opacity values from the range 0 to 1 must be converted into a percentage, as shown above.

Upvotes: 11

Gavin
Gavin

Reputation: 7944

You can easily do it like this in all modern browsers:

color: rgb(from #ff0000 r g b / .5)

or with a CSS variable:

color: rgb(from var(--your-color-var) r g b / .5)

This is part of the newer CSS specificcation called CSS Color Module Level 4

Upvotes: 4

Vahe Aslanyan
Vahe Aslanyan

Reputation: 126

In scss you can use the following:

background-color: rgba($color: #000088, $alpha: 0.5);

Upvotes: 5

Jeremy Lynch
Jeremy Lynch

Reputation: 7210

Sass has red, green, blue to extract to channels from a hex color:

background-color: rgba(red($hex_color), green($hex_color), blue($hex_color), 0.2);

Sass also has rgba($hex_color, $alpha)

Upvotes: 27

Oded Breiner
Oded Breiner

Reputation: 29729

#rrggbbaa notation is fully supported in Chrome 62+ and all other evergreen browsers:

background: #56ff0077;

Upvotes: 49

Oliver Engelhardt
Oliver Engelhardt

Reputation: 1

how about using an :after pseudo-element?

#myDiv{
  position: relative;
  width: 128px;
  height: 128px;
  background-color: #ccc;
}

#myDiv:after{
  content: '';
  position: absolute;
  left: 0; 
  top: 0;
  width: 100%; 
  height: 100%;
  pointer-events: none;
  
  /* here you go */
  margin: -8px;
  border: solid 8px #00f;
  opacity: 0.2;
}
<div id="myDiv">hello world!</div>

Upvotes: -3

metal maniac
metal maniac

Reputation: 119

If you have all your colors in HEX variables, you can use the following SCSS code:

First, copy this mapping from rgba - opacity values to hex codes:

    $opacity-to-hex: (
    0: '00',
    0.05: '0C',
    0.1: '19',
    0.15: '26',
    0.2: '33',
    0.25: '3F',
    0.3: '4C',
    0.35: '59',
    0.4: '66',
    0.45: '72',
    0.5: '7F',
    0.55: '8C',
    0.6: '99',
    0.65: 'A5',
    0.7: 'B2',
    0.75: 'BF',
    0.8: 'CC',
    0.85: 'D8',
    0.9: 'E5',
    0.95: 'F2',
    1: 'FF'
)

Then copy the following mixin that uses the mapping:

@mixin color-opacity($property, $color, $opacity) {
    #{$property}: unquote($color + map-get($opacity-to-hex, $opacity));
}

Last but not least, you can use this mixin with the mapped opacity on all color-properties, e.g. like this:

@include color-opacity('background-color', $your_hex_color, 0.8);
@include color-opacity('color', $your_hex_color, 0.5);

Upvotes: 7

iwis
iwis

Reputation: 1712

In Sass we can write:

background-color: rgba(#ff0000, 0.5);

as it was suggested in Hex representation of a color with alpha channel?

Upvotes: 18

James Donnelly
James Donnelly

Reputation: 128771

The CSS Color Module Level 4 will probably support 4 and 8-digit hexadecimal RGBA notation!

Three weeks ago (18th of December 2014) the CSS Color Module Level 4 editor's draft was submitted to the CSS W3C Working Group. Though in a state which is heavily susceptible to change, the current version of the document implies that in the somewhat near future CSS will support both the 4 and 8-digit hexadecimal RGBA notation.

Note: the following quote has irrelevant chunks cut out and the source may have been heavily modified by the time you read this (as mentioned above, it's an editor's draft and not a finalised document).
If things have heavily changed, please leave a comment letting me know so I can update this answer!

§ 4.2. The RGB hexadecimal notations: #RRGGBB

The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits. In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00).

8 digits

The first 6 digits are interpreted identically to the 6-digit notation. The last pair of digits, interpreted as a hexadecimal number, specifies the alpha channel of the color, where 00 represents a fully transparent color and ff represent a fully opaque color.

Example 3
In other words, #0000ffcc represents the same color as rgba(0, 0, 100%, 80%) (a slightly-transparent blue).

4 digits

This is a shorter variant of the 8-digit notation, "expanded" in the same way as the 3-digit notation is. The first digit, interpreted as a hexadecimal number, specifies the red channel of the color, where 0 represents the minimum value and f represents the maximum. The next three digits represent the green, blue, and alpha channels, respectively.

What does this mean for the future of CSS colours?

This means that assuming this isn't completely removed from the Level 4 document, we'll soon be able to define our RGBA colours (or HSLA colours, if you're one of those guys) in hexadecimal format in browsers which support the Color Module Level 4's syntax.

Example

elem {
    background: rgb(0, 0, 0);           /* RGB notation (no alpha). */
    background: #000;                   /* 3-digit hexadecimal notation (no alpha). */
    background: #000000;                /* 6-digit hexadecimal notation (no alpha). */
    background: rgba(0, 0, 0, 1.0);     /* RGBA notation. */

    /* The new 4 and 8-digit hexadecimal notation. */
    background: #0000;                  /* 4-digit hexadecimal notation. */
    background: #00000000;              /* 8-digit hexadecimal notation. */
}

When will I be able to use this in my client-facing products?

Tumble weed is the only real response...

All jokes aside: it's currently only the start of 2015, so these will not be supported in any browser for quite some time yet - even if your product is only designed to work on the most up-to-date of browsers you'll probably not be seeing this in action in a production browser any time soon.

View current browser support for #RRGGBBAA color notation

However, that said, the way CSS works means that we can actually start using these today! If you really want to start using them right now, as long as you add a fall back any non-supporting browsers will simply ignore the new properties until they are deemed valid:

figure {
  margin: 0;
  padding: 4px;
  
  /* Fall back (...to browsers which don't support alpha transparency). */
  background: #FEFE7F;
  color: #3F3FFE;
  
  /* Current 'modern' browser support. */
  background: rgba(255, 255, 0, 0.5);
  color: rgba(0, 0, 255, 0.75);
  
  /* Fall... foward? */
  background: #ffff007F; /* Or, less accurately, #ff08 */
  color: #0000ffbe;      /* Or #00fc */
}
<figure>Hello, world!</figure>

As long as you're viewing this answer on a browser which supports the background and color properties in CSS, the <figure> element in result of the above snippet will look very similar to this:

Code Snippet Result Image

Using the most recent version of Chrome on Windows (v39.0.2171) to inspect our <figure> element, we'll see the following:

Element Inspector Example

The 6-digit hexadecimal fall back is overridden by the rgba() values, and our 8-digit hexadecimal values are ignored as they are currently deemed invalid by Chrome's CSS parser. As soon as our browser supports these 8-digit values, these will override the rgba() ones.

UPDATE 2018-07-04: Firefox, Chrome and Safari are support this notation now, Edge still missing but will probably follow (https://caniuse.com/#feat=css-rrggbbaa).

Upvotes: 177

Julian Mann
Julian Mann

Reputation: 6466

If you can use LESS, there is a fade function.

@my-opaque-color: #a438ab;
@my-semitransparent-color: fade(@my-opaque-color, 50%);

background-color:linear-gradient(to right,@my-opaque-color, @my-semitransparent-color); 

// result: 
background-color: linear-gradient(to right, #a438ab, rgba(164, 56, 171, 0.5));

Upvotes: 6

Lajos M&#233;sz&#225;ros
Lajos M&#233;sz&#225;ros

Reputation: 3871

Charming Prince:

Only internet explorer allows the 4 byte hex color in the format of ARGB, where A is the Alpha channel. It can be used in gradient filters for example:

filter  : ~"progid:DXImageTransform.Microsoft.Gradient(GradientType=@{dir},startColorstr=@{color1},endColorstr=@{color2})";

Where dir can be: 1(horizontal) or 0(vertical) And the color strings can be hex colors(#FFAAD3) or argb hex colors(#88FFAAD3).

Upvotes: 2

Charming Prince
Charming Prince

Reputation: 489

why not use background-color: #ff0000; opacity: 0.5; filter: alpha(opacity=50); /* in IE */

if you target a color for a text or probably an element, this should be a lot easier to do.

Upvotes: -4

T9b
T9b

Reputation: 3502

I found the answer after posting the enhancement to the question. Sorry!

MS Excel helped!

simply add the Hex prefix to the hex colour value to add an alpha that has the equivalent opacity as the % value.

(in rbga the percentage opacity is expressed as a decimal as mentioned above)

Opacity %   255 Step        2 digit HEX prefix
0%          0.00            00
5%          12.75           0C
10%         25.50           19
15%         38.25           26
20%         51.00           33
25%         63.75           3F
30%         76.50           4C
35%         89.25           59
40%         102.00          66
45%         114.75          72
50%         127.50          7F
55%         140.25          8C
60%         153.00          99
65%         165.75          A5
70%         178.50          B2
75%         191.25          BF
80%         204.00          CC
85%         216.75          D8
90%         229.50          E5
95%         242.25          F2
100%        255.00          FF

Upvotes: 121

user900360
user900360

Reputation:

Well, different color notations is what you will have to learn.
Kuler gives you a better chance to find color and in multiple notations.
Hex is not different from RGB, FF = 255 and 00 = 0, but that's what you know. So in a way, you have to visualize it.
I use Hex, RGBA and RGB. Unless mass conversion is required, manually doing this will help you remember some odd 100 colors and their codes.
For mass conversion write some script like one given by Alarie. Have a blast with Colors.

Upvotes: 0

James Alarie
James Alarie

Reputation: 271

RGB='#ffabcd';
A='0.5';
RGBA='('+parseInt(RGB.substring(1,3),16)+','+parseInt(RGB.substring(3,5),16)+','+parseInt(RGB.substring(5,7),16)+','+A+')';

Upvotes: 27

Madara&#39;s Ghost
Madara&#39;s Ghost

Reputation: 174937

I'm afraid that's not possible. the rgba format you know is the only one.

Upvotes: 8

Griffin
Griffin

Reputation: 14584

See here http://www.w3.org/TR/css3-color/#rgba-color

It is not possible, most probably because 0xFFFFFFFF is greater than the maximum value for 32bit integers

Upvotes: 14

Related Questions