Skip to content

Commit

Permalink
Reorganize and update the FAQ.
Browse files Browse the repository at this point in the history
  • Loading branch information
ubernostrum committed Jun 6, 2024
1 parent 0f865b2 commit 41046b0
Showing 1 changed file with 86 additions and 75 deletions.
161 changes: 86 additions & 75 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,71 @@ The following notes answer common questions, and may be useful to you when
using ``webcolors``.


General
-------

What versions of Python are supported?
--------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Version |release| of ``webcolors`` supports and is tested on Python 3.8, 3.9,
3.10, 3.11, and 3.12.


How am I allowed to use this module?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The ``webcolors`` module is distributed under a `three-clause BSD license
<http://opensource.org/licenses/BSD-3-Clause>`_. This is an open-source license
which grants you broad freedom to use, redistribute, modify and distribute
modified versions of ``webcolors``. For details, see the file ``LICENSE`` in
the source distribution of ``webcolors``.

.. _three-clause BSD license: http://opensource.org/licenses/BSD-3-Clause


I found a bug or want to make an improvement!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The canonical development repository for ``webcolors`` is online at
<https://github.com/ubernostrum/webcolors>. Issues and pull requests can both
be filed there.


How closely does this module follow the standards?
--------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

As closely as is practical (see below regarding floating-point values), within
:ref:`the supported formats <support>`; the ``webcolors`` module was written
with the relevant standards documents close at hand. See :ref:`the conformance
documentation <conformance>` for details.


Why aren't ``rgb_to_rgb_percent()`` and ``rgb_percent_to_rgb()`` precise?
-------------------------------------------------------------------------
Design choices and technical details
------------------------------------

This is due to limitations in the representation of floating-point numbers in
programming languages. Python, like many programming languages, uses `IEEE
floating-point <https://en.wikipedia.org/wiki/IEEE_754>`_, which is inherently
imprecise for some values. This imprecision only appears when converting
between integer and percentage ```rgb()``` triplets, as in
:func:`~webcolors.rgb_to_rgb_percent` and
:func:`~webcolors.rgb_percent_to_rgb`.

To work around this, some common values (255, 128, 64, 32, 16 and 0) are
handled as special cases, with hard-coded precise results. For all other
values, conversion to percentage ``rgb()`` triplet uses a standard Python
:class:`float`, rounding the result to two decimal places.
Why not use a more object-oriented design with classes for the colors?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

See :ref:`the conformance documentation <conformance>` for details on how this
affects testing.
Representing color values with Python classes would introduce overhead for no
real gain. Real-world use cases tend to involve working directly with the
actual values, so settling on conventions for how to represent them as Python
types, and then offering a function-based interface, accomplishes everything
needed without the additional indirection layer of having to instantiate and
serialize a color-wrapping object.

Keeping a function-based interface also maintains consistency with Python's
built-in :mod:`colorsys` module which has the same style of interface for
converting amongst color spaces.

Note that if an object-oriented interface is desired, `the third-party
colormath module <https://pypi.org/project/colormath/>`_ does have a
class-based interface (and rightly so, as it offers a wider range of color
representation and manipulation options than ``webcolors``).


Why does ``webcolors`` prefer American spellings?
-------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In CSS3, several color names are defined multiple times with identical values,
to support both American and British spelling variants for
Expand All @@ -65,72 +92,56 @@ and CSS2, each of which only allowed `gray`.


Why aren't HSL values supported?
--------------------------------

In the author's experience, actual use of HSL values on the web is extremely
rare; the overwhelming majority of all colors used on the web are specified
using sRGB, through hexadecimal color values or through integer or percentage
``rgb()`` triplets. This decreases the importance of supporting the ``hsl()``
construct.

Additionally, Python already has the :mod:`colorsys` module in the standard
library, which offers functions for converting between RGB, HSL, HSV and YIQ
color systems. If you need conversion to/from HSL or another color system, use
:mod:`colorsys`.


Why aren't alpha-channel constructs like ``rgba()`` supported?
--------------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Because the alpha-channel information can't really be usefully converted. As of
CSS3, the ``hsla()`` construct is the only other color format that carries
alpha-channel information, and as explained above, HSL colors are not supported
in this module.
The :mod:`colorsys` module in the standard library contains functions for
converting between RGB, HSL, HSV and YIQ color systems, so you can convert
integer RGB triplets from ``webcolors`` to HSL triplets, or vice-versa, using
:mod:`colorsys`, without ``webcolors`` needing to provide its own conversion
functions.

The W3C CSS Colors Level 4 module does provide an 8-digit hexadecimal color
representation where the final two digits carry alpha-channel
information. Support for its alpha-channel constructs in this module may
eventually be re-evaluated, though it would likely still be limited to
converting between only those constructs which carry alpha-channel information
(for example, an ``rgba()`` or an eight-digit hexadecimal color value could not
be losslessly round-tripped to a color name and back).

Why aren't ``rgb_to_rgb_percent()`` and ``rgb_percent_to_rgb()`` precise?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Why not use a more object-oriented design with classes for the colors?
----------------------------------------------------------------------

Representing color values with Python classes would introduce overhead for no
real gain. Real-world use cases tend to involve working directly with the
actual values, so settling on conventions for how to represent them as Python
types, and then offering a function-based interface, accomplishes everything
needed without the additional indirection layer of having to instantiate and
serialize a color-wrapping object.

Keeping a function-based interface also maintains consistency with Python's
built-in :mod:`colorsys` module which has the same style of interface for
converting amongst color spaces.
This is due to limitations in the representation of floating-point numbers in
programming languages. Python, like many programming languages, uses `IEEE
floating-point <https://en.wikipedia.org/wiki/IEEE_754>`_, which is inherently
imprecise for some values. This imprecision only appears when converting
between integer and percentage ```rgb()``` triplets, as in
:func:`~webcolors.rgb_to_rgb_percent` and
:func:`~webcolors.rgb_percent_to_rgb`.

Note that if an object-oriented interface is desired, `the third-party
colormath module <https://pypi.org/project/colormath/>`_ does have a
class-based interface (and rightly so, as it offers a wider range of color
representation and manipulation options than ``webcolors``).
To work around this, some common values (255, 128, 64, 32, 16 and 0) are
handled as special cases, with hard-coded precise results. For all other
values, conversion to percentage ``rgb()`` triplet uses a standard Python
:class:`float`, rounding the result to two decimal places.

See :ref:`the conformance documentation <conformance>` for details on how this
affects testing.

How am I allowed to use this module?
------------------------------------

The ``webcolors`` module is distributed under a `three-clause BSD license
<http://opensource.org/licenses/BSD-3-Clause>`_. This is an open-source license
which grants you broad freedom to use, redistribute, modify and distribute
modified versions of ``webcolors``. For details, see the file ``LICENSE`` in
the source distribution of ``webcolors``.
Are alpha-channel constructs like ``rgba()`` supported?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. _three-clause BSD license: http://opensource.org/licenses/BSD-3-Clause
While this decision may be re-evaluated in the future, ``webcolors`` currently
does *not* support constructs which carry alpha-channel information (the
``rgba()`` and ``hsla()`` constructs of CSS3, or the ``#rrggbbaa`` construct of
the CSS Colors Level 4 module).

There are two main reasons for this:

I found a bug or want to make an improvement!
---------------------------------------------
1. ``webcolors`` does not yet support the CSS Color Module Level 4 in any way,
which means the only supported construct would be ``rgba()`` (since
``webcolors`` only handles RGB color constructs, not HSL), and there would
be no other alpha-channel construct to convert to or from.

The canonical development repository for ``webcolors`` is online at
<https://github.com/ubernostrum/webcolors>. Issues and pull requests can both
be filed there.
2. Once support for the CSS Color Module Level 4 is finalized, it's still not
clear that converting between ``rgba()`` and ``#rrggbbaa`` constructs would
be useful enough on its own to justify the support. Converting to
non-alpha-channel constructs would not require specialized functions since
the alpha-channel component could simply be sliced off, and converting
_from_ non-alpha-channel constructs to alpha-channel constructs similarly
does not seem to require additional functions -- the desired alpha-channel
information could be appended onto a non-alpha-channel construct easily
enough.

0 comments on commit 41046b0

Please sign in to comment.