diff --git a/tqdm/_tqdm.py b/tqdm/_tqdm.py
--- a/tqdm/_tqdm.py
+++ b/tqdm/_tqdm.py
@@ -13,7 +13,7 @@
 # compatibility functions and utilities
 from ._utils import _supports_unicode, _environ_cols_wrapper, _range, _unich, \
     _term_move_up, _unicode, WeakSet, _basestring, _OrderedDict, \
-    Comparable
+    Comparable, RE_ANSI
 from ._monitor import TMonitor
 # native libraries
 import sys
@@ -360,10 +360,11 @@ def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
                     # Else no progress bar, we can just format and return
                     return bar_format.format(**bar_args)
 
-            # Formatting progress bar
-            # space available for bar's display
-            N_BARS = max(1, ncols - len(l_bar) - len(r_bar)) if ncols \
-                else 10
+            # Formatting progress bar space available for bar's display
+            if ncols:
+                N_BARS = max(1, ncols - len(RE_ANSI.sub('', l_bar + r_bar)))
+            else:
+                N_BARS = 10
 
             # format bar depending on availability of unicode/ascii chars
             if ascii:
diff --git a/tqdm/_utils.py b/tqdm/_utils.py
--- a/tqdm/_utils.py
+++ b/tqdm/_utils.py
@@ -1,11 +1,13 @@
 import os
 import subprocess
 from platform import system as _curos
+import re
 CUR_OS = _curos()
 IS_WIN = CUR_OS in ['Windows', 'cli']
 IS_NIX = (not IS_WIN) and any(
     CUR_OS.startswith(i) for i in
     ['CYGWIN', 'MSYS', 'Linux', 'Darwin', 'SunOS', 'FreeBSD', 'NetBSD'])
+RE_ANSI = re.compile(r"\x1b\[[;\d]*[A-Za-z]")
 
 
 # Py2/3 compat. Empty conditional to avoid coverage

diff --git a/tqdm/tests/tests_tqdm.py b/tqdm/tests/tests_tqdm.py
--- a/tqdm/tests/tests_tqdm.py
+++ b/tqdm/tests/tests_tqdm.py
@@ -255,6 +255,19 @@ def test_format_meter():
         unich(0x258f) + "|test"
 
 
+def test_ansi_escape_codes():
+    """Test stripping of ANSI escape codes"""
+    format_meter = tqdm.format_meter
+    ansi = {'BOLD': '\033[1m',
+            'RED': '\033[91m',
+            'END': '\033[0m'}
+    desc = '{BOLD}{RED}Colored{END} description'.format(**ansi)
+    ncols = 123
+    ansi_len = sum([len(code) for code in ansi.values()])
+    meter = format_meter(0, 100, 0, ncols=ncols, prefix=desc)
+    assert len(meter) == ncols + ansi_len
+
+
 def test_si_format():
     """Test SI unit prefixes"""
     format_meter = tqdm.format_meter

Bar length not calculated correctly when ANSI color codes are used
I am using ANSI color codes in the progress bar description string to emphasize success, failure etc.

Unfortunately, the bar length calculation doesn't work as expected with these color codes.

In the example below, the bar stops short of the terminal width by 13 characters, which is the combined length of the ANSI control sequences.

```python
from tqdm import tqdm

ansi = {'BOLD': '\033[1m',
        'RED': '\033[91m',
        'END': '\033[0m'}

text = '{BOLD}{RED}Failed{END}: ...'.format(**ansi)

pbar = tqdm(total=100, desc=text)
pbar.close()
```

Output (example):
```
Failed: ...:   0%|                                  | 0/100 [00:00<?, ?it/s]
```
Expected:
```
Failed: ...:   0%|                                               | 0/100 [00:00<?, ?it/s]
```

This should be as easy to fix as stripping the ANSI codes away as in the code below when doing the length calculations here: https://github.com/tqdm/tqdm/blob/master/tqdm/_tqdm.py#L365

```python
import re
re_ansi = re.compile(r"\x1b\[[;\d]*[A-Za-z]")
stripped = re_ansi.sub('', text)
print(len(text))  # 24
print(len(stripped))  # 11
```

I'd be happy to submit a PR, but I don't know if this is a desired feature. Performance should not be an issue, as the stripping executes in < 1 µs.

---

```
 >>> print(tqdm.__version__)
4.24.0
>>> print(sys.version)
3.7.0 (default, Jun 28 2018, 07:39:16) 
[Clang 4.0.1 (tags/RELEASE_401/final)]
>>> print(sys.platform)
darwin
```

Thanks. Maybe we should strip escape sequences... related to #450
tqdm/tests/tests_tqdm.py::test_format_interval tqdm/tests/tests_tqdm.py::test_format_meter tqdm/tests/tests_tqdm.py::test_si_format tqdm/tests/tests_tqdm.py::test_all_defaults tqdm/tests/tests_tqdm.py::test_iterate_over_csv_rows tqdm/tests/tests_tqdm.py::test_file_output tqdm/tests/tests_tqdm.py::test_leave_option tqdm/tests/tests_tqdm.py::test_trange tqdm/tests/tests_tqdm.py::test_min_interval tqdm/tests/tests_tqdm.py::test_max_interval tqdm/tests/tests_tqdm.py::test_min_iters tqdm/tests/tests_tqdm.py::test_dynamic_min_iters tqdm/tests/tests_tqdm.py::test_big_min_interval tqdm/tests/tests_tqdm.py::test_smoothed_dynamic_min_iters tqdm/tests/tests_tqdm.py::test_smoothed_dynamic_min_iters_with_min_interval tqdm/tests/tests_tqdm.py::test_disable tqdm/tests/tests_tqdm.py::test_unit tqdm/tests/tests_tqdm.py::test_ascii tqdm/tests/tests_tqdm.py::test_update tqdm/tests/tests_tqdm.py::test_close tqdm/tests/tests_tqdm.py::test_smoothing tqdm/tests/tests_tqdm.py::test_deprecated_nested tqdm/tests/tests_tqdm.py::test_bar_format tqdm/tests/tests_tqdm.py::test_unpause tqdm/tests/tests_tqdm.py::test_position tqdm/tests/tests_tqdm.py::test_set_description tqdm/tests/tests_tqdm.py::test_deprecated_gui tqdm/tests/tests_tqdm.py::test_cmp tqdm/tests/tests_tqdm.py::test_repr tqdm/tests/tests_tqdm.py::test_clear tqdm/tests/tests_tqdm.py::test_clear_disabled tqdm/tests/tests_tqdm.py::test_refresh tqdm/tests/tests_tqdm.py::test_disabled_refresh tqdm/tests/tests_tqdm.py::test_write tqdm/tests/tests_tqdm.py::test_len tqdm/tests/tests_tqdm.py::test_autodisable_disable tqdm/tests/tests_tqdm.py::test_autodisable_enable tqdm/tests/tests_tqdm.py::test_deprecation_exception tqdm/tests/tests_tqdm.py::test_postfix tqdm/tests/tests_tqdm.py::test_postfix_direct tqdm/tests/tests_tqdm.py::test_file_redirection tqdm/tests/tests_tqdm.py::test_external_write tqdm/tests/tests_tqdm.py::test_unit_scale tqdm/tests/tests_tqdm.py::test_threading tqdm/tests/tests_tqdm.py::test_bool tqdm/tests/tests_tqdm.py::test_autonotebook
tqdm/tests/tests_tqdm.py::test_ansi_escape_codes