Jump to content
Wikipedia The Free Encyclopedia

Module:Color contrast

From Wikipedia, the free encyclopedia
Module documentation[view] [edit] [history] [purge]
This module is rated as ready for general use. It has reached a mature state, is considered relatively stable and bug-free, and may be used wherever appropriate. It can be mentioned on help pages and other Wikipedia resources as an option for new users. To minimise server load and avoid disruptive output, improvements should be developed through sandbox testing rather than repeated trial-and-error editing.
Page template-protected This module is currently protected from editing.
See the protection policy and protection log for more details. Please discuss any changes on the talk page; you may submit an edit request to ask an administrator to make an edit if it is uncontroversial or supported by consensus. You may also request that this page be unprotected.
Warning This Lua module is used on approximately 548,000 pages .
To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them.
This module depends on the following other modules:

This module is used primarily by

It is also used for tracking within

and for documentation in

The formulas used are stated in WCAG 2.x specifications. WCAG is the main guideline for creating accessible interfaces on the web.

Usage

To use this module, you may use one of the above listed templates or invoke the module directly

  • To compute relative luminescence:
    {{RGBColorToLum|color}} or {{#invoke:Color contrast|lum|color}}
  • To compute a contrast ratio between two colors:
    {{Color contrast ratio|color1|color2|error=?}} or {{#invoke:Color contrast|ratio|color1|color2|error=?}}
  • To determine which of two colors (color2a and color2b) has the greater contrast ratio with a particular color (color1):
    {{Greater color contrast ratio|color1|color2a|color2b}} or {{#invoke:Color contrast|greatercontrast|color1|color2a|color2b}}
  • To compute the contrast ratio between the background and text colors specified in a css style string:
    {{#invoke:Color contrast|styleratio|css style statement string|default background color|default text color}}
The above documentation is transcluded from Module:Color contrast/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Subpages of this module.

 --
 -- This module implements
 -- {{Color contrast ratio}}
 -- {{Greater color contrast ratio}}
 -- {{ColorToLum}}
 -- {{RGBColorToLum}}
 --
 localp={}
 localHTMLcolor=mw.loadData('Module:Color contrast/colors')

 localfunctionsRGB(v)
 if(v<=0.03928)then
 v=v/12.92
 else
 v=math.pow((v+0.055)/1.055,2.4)
 end
 returnv
 end

 localfunctionrgbdec2lum(R,G,B)
 if(0<=RandR<256and0<=GandG<256and0<=BandB<256)then
 return0.2126*sRGB(R/255)+0.7152*sRGB(G/255)+0.0722*sRGB(B/255)
 else
 return''
 end
 end

 localfunctionhsl2lum(h,s,l)
 if(0<=handh<360and0<=sands<=1and0<=landl<=1)then
 localc=(1-math.abs(2*l-1))*s
 localx=c*(1-math.abs(math.fmod(h/60,2)-1))
 localm=l-c/2

 localr,g,b=m,m,m
 if(0<=handh<60)then
 r=r+c
 g=g+x
 elseif(60<=handh<120)then
 r=r+x
 g=g+c
 elseif(120<=handh<180)then
 g=g+c
 b=b+x
 elseif(180<=handh<240)then
 g=g+x
 b=b+c
 elseif(240<=handh<300)then
 r=r+x
 b=b+c
 elseif(300<=handh<360)then
 r=r+c
 b=b+x
 end
 returnrgbdec2lum(255*r,255*g,255*b)
 else
 return''
 end
 end

 localfunctioncolor2lum(c)

 if(c==nil)then
 return''
 end

 -- html '#' entity
 c=c:gsub("&#35;","#")

 -- whitespace
 c=c:match('^%s*(.-)[%s;]*$')

 -- unstrip nowiki strip markers
 c=mw.text.unstripNoWiki(c)

 -- lowercase
 c=c:lower()

 -- first try to look it up
 localL=HTMLcolor[c]
 if(L~=nil)then
 returnL
 end

 -- convert from hsl
 ifmw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$')then
 localh,s,l=mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
 returnhsl2lum(tonumber(h),tonumber(s)/100,tonumber(l)/100)
 end

 -- convert from rgb
 ifmw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$')then
 localR,G,B=mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$')
 returnrgbdec2lum(tonumber(R),tonumber(G),tonumber(B))
 end

 -- convert from rgb percent
 ifmw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$')then
 localR,G,B=mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
 returnrgbdec2lum(255*tonumber(R)/100,255*tonumber(G)/100,255*tonumber(B)/100)
 end

 -- remove leading # (if there is one) and whitespace
 c=mw.ustring.match(c,'^[%s#]*([a-f0-9]*)[%s]*$')

 -- split into rgb
 localcs=mw.text.split(cor'','')
 if(#cs==6)then
 localR=16*tonumber('0x'..cs[1])+tonumber('0x'..cs[2])
 localG=16*tonumber('0x'..cs[3])+tonumber('0x'..cs[4])
 localB=16*tonumber('0x'..cs[5])+tonumber('0x'..cs[6])

 returnrgbdec2lum(R,G,B)
 elseif(#cs==3)then
 localR=16*tonumber('0x'..cs[1])+tonumber('0x'..cs[1])
 localG=16*tonumber('0x'..cs[2])+tonumber('0x'..cs[2])
 localB=16*tonumber('0x'..cs[3])+tonumber('0x'..cs[3])

 returnrgbdec2lum(R,G,B)
 end

 -- failure, return blank
 return''
 end

 -- This exports the function for use in other modules.
 -- The colour is passed as a string.
 functionp._lum(color)
 returncolor2lum(color)
 end

 functionp._greatercontrast(args)
 localbias=tonumber(args['bias']or'0')or0
 localcss=(args['css']andargs['css']~='')andtrueorfalse
 localv1=color2lum(args[1]or'')
 localc2=args[2]or'white'
 localv2=color2lum(c2)
 localc3=args[3]or'black'
 localv3=color2lum(c3)
 localratio1=-1;
 localratio2=-1;
 if(type(v1)=='number'andtype(v2)=='number')then
 ratio1=(v2+0.05)/(v1+0.05)
 ratio1=(ratio1<1)and1/ratio1orratio1
 end
 if(type(v1)=='number'andtype(v3)=='number')then
 ratio2=(v3+0.05)/(v1+0.05)
 ratio2=(ratio2<1)and1/ratio2orratio2
 end

 ifcssthen
 localc1=args[1]or''
 ifmw.ustring.match(c1,'^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$')or
 mw.ustring.match(c1,'^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$')then
 c1='#'..c1
 end
 ifmw.ustring.match(c2,'^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$')or
 mw.ustring.match(c2,'^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$')then
 c2='#'..c2
 end
 ifmw.ustring.match(v3,'^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$')or
 mw.ustring.match(v3,'^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$')then
 c3='#'..c3
 end
 return'background-color:'..c1..'; color:'..((ratio1>0)and(ratio2>0)and((ratio1+bias>ratio2)andc2orc3)or'')..';'
 end

 return(ratio1>0)and(ratio2>0)and((ratio1+bias>ratio2)andc2orc3)or''
 end

 functionp._ratio(args)
 localv1=color2lum(args[1])
 localv2=color2lum(args[2])
 if(type(v1)=='number'andtype(v2)=='number')then
 -- v1 should be the brighter of the two.
 ifv2>v1then
 v1,v2=v2,v1
 end
 return(v1+0.05)/(v2+0.05)
 else
 returnargs['error']or'?'
 end
 end

 functionp._styleratio(args)
 localstyle=(args[1]or''):lower()
 localbg,fg='white','black'
 locallum_bg,lum_fg=1,0

 ifargs[2]then
 locallum=color2lum(args[2])
 iflum~=''thenbg,lum_bg=args[2],lumend
 end
 ifargs[3]then
 locallum=color2lum(args[3])
 iflum~=''thenfg,lum_fg=args[3],lumend
 end

 localslist=mw.text.split(mw.ustring.gsub(mw.ustring.gsub(styleor'','&#[Xx]23;','#'),'&#35;','#'),';')
 fork=1,#slistdo
 locals=slist[k]
 localk,v=s:match('^[%s]*([^:]-):([^:]-)[%s;]*$')
 k=kor''
 v=vor''
 if(k:match('^[%s]*(background)[%s]*$')ork:match('^[%s]*(background%-color)[%s]*$'))then
 locallum=color2lum(v)
 if(lum~='')thenbg,lum_bg=v,lumend
 elseif(k:match('^[%s]*(color)[%s]*$'))then
 locallum=color2lum(v)
 if(lum~='')thenbg,lum_fg=v,lumend
 end
 end
 iflum_bg>lum_fgthen
 return(lum_bg+0.05)/(lum_fg+0.05)
 else
 return(lum_fg+0.05)/(lum_bg+0.05)
 end
 end

 --[[
 Use {{#invoke:Color contrast|somecolor}} directly or
 {{#invoke:Color contrast}} from a wrapper template.

 Parameters:
 	-- |1=	— required; A color to check.
 --]]
 functionp.lum(frame)
 localcolor=frame.args[1]orframe:getParent().args[1]
 returnp._lum(color)
 end

 functionp.ratio(frame)
 localargs=frame.args[1]andframe.argsorframe:getParent().args
 returnp._ratio(args)
 end

 functionp.styleratio(frame)
 localargs=frame.args[1]andframe.argsorframe:getParent().args
 returnp._styleratio(args)
 end

 functionp.greatercontrast(frame)
 localargs=frame.args[1]andframe.argsorframe:getParent().args
 returnp._greatercontrast(args)
 end

 returnp

AltStyle によって変換されたページ (->オリジナル) /