26

I am sure this must of been asked before but can't find any in the search. What is the fastest way to ensure all non safe characters are removed from a string allowing it to be used in a CSS class name?

1

7 Answers 7

37

I would replace anything that is not a lowercase letter or digit, and then I would add a special prefix to avoid collisions with class names you have used for other purposes. For example, here is one possible way:

function makeSafeForCSS(name) {
    return name.replace(/[^a-z0-9]/g, function(s) {
        var c = s.charCodeAt(0);
        if (c == 32) return '-';
        if (c >= 65 && c <= 90) return '_' + s.toLowerCase();
        return '__' + ('000' + c.toString(16)).slice(-4);
    });
}

// shows "prefix_c_a_p_s-numb3rs-__0024ymbols"
alert("prefix" + makeSafeForCSS("CAPS numb3rs $ymbols"));
Sign up to request clarification or add additional context in comments.

1 Comment

CSS class names cannot begin with a digit. This function does not sanitize class names such as "123class"
14

If you mean the following symbols

!"#$%&'()*+,./:;<=>?@[\]^`{|}~

then just replace them with nothing:

names = names.replace(/[!\"#$%&'\(\)\*\+,\.\/:;<=>\?\@\[\\\]\^`\{\|\}~]/g, '');

(I may have added an extra, or not enough, escape characters in there)

Here is a quick demo.

But just so you know, not all of those symbols are "unsafe", you could just escape the symbol when targeting the class name (ref).

4 Comments

This won't catch international characters (e.g. à, è, ì, ò, ù, À, È, Ì, Ò, Ù).
@NexusRex those are all valid to use in class names. In fact, just about anything is valid if escaped properly; this now includes id's in HTML5. See also this page.
Does not catch whitespace. \s added to the regex resolves this
Without extra escapes: /[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g
4

I use this for my selectors, IDs or classes names:

String.prototype.safeCSSId = function() {
  return encodeURIComponent(this)
    .toLowerCase()
    .replace(/\.|%[0-9a-z]{2}/gi, '');
}

console.log("The dæmon is in the detail.".safeCSSId());

Comments

1

You can try the urlify.js from django.

Get it from: https://github.com/django/django/blob/master/django/contrib/admin/static/admin/js/urlify.js

Comments

1

Check out how the Wordpress PHP function sanitize_html_class() is implemented. Should be straight forward to translate into JS.

function sanitize_html_class( $classname, $fallback = '' ) {
    // Strip out any percent-encoded characters.
    $sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $classname );

    // Limit to A-Z, a-z, 0-9, '_', '-'.
    $sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $sanitized );

    if ( '' === $sanitized && $fallback ) {
        return sanitize_html_class( $fallback );
    }
    /**
     * Filters a sanitized HTML class string.
     *
     * @since 2.8.0
     *
     * @param string $sanitized The sanitized HTML class.
     * @param string $classname HTML class before sanitization.
     * @param string $fallback  The fallback string.
     */
    return apply_filters( 'sanitize_html_class', $sanitized, $classname, $fallback );
}

Comments

0

If anyone is interested in the coffee way of this:

window.make_safe_for_css = (name) ->
    name.replace /[^a-z0-9]/g, (s) ->
        c = s.charCodeAt(0)
        if c == 32 then return '-'
        if c >= 65 && c <= 90 then return '_' + s.toLowerCase()
        '__' + '000' + c.toString(16).slice -4

2 Comments

What's "coffee" way?
@HashimAziz CoffeScript.
-1

with jQuery:

$.escapeSelector(stringToEscape);

Edit: Misunderstood the original question. This can be used e.g. when querying an element by class name but not for generating the class names.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.