lebolo
lebolo

Reputation: 2160

CSS pseudo-element checkmark outside of element

I'm trying to create a checkbox with a background color via CSS. My HTML looks like:

<div class="filter-group">
    <!---some label--->
    <ul class="filter-options scrollable">
        <li class="filter-facet"><span class="label-text">Foo 1 </span><span class="muted count">(101)</span></li>
        <!--other items-->
    </ul>
</div>

However, I'm running into various problems (you can follow along at the jsFiddle or in the code snippet at the end).

1) inline-block

enter image description here

When I set display: inline-block so that I can set a width and height of 1em, the checkmark shows up outside of the colored element.

Why does this occur and how do I get the checkmark inside?

.filter-facet::before {
    background-color: lightblue;
    display: inline-block;
    width: 1em;
    height: 1em;
    margin: 0 5px 0 0;
    vertical-align: text-top;
    border: 1px solid black;
}

.filter-facet:not(.filtered)::before {
    content:'\2713';
    text-shadow: 1px 1px 1px black;
}

.filter-facet.filtered::before {
    content:'';
}

2) inline

Width not controlled

When I don't set display it gets defaulted to inline, which means I can no longer set the width or height. The checkmark shows up inside the element, but unchecking the box makes the element shrink to nothing. I tried putting in some non-breaking spaces (\00A0), but even if it did work it would seem a bit messy.

Can I control the width/height of an inline element?

.filter-facet::before {
    background-color: lightblue;
    /*display: inline-block;*/ /*inline by default*/
    width: 1em; /*ignored, since it's inline*/
    height: 1em; /*ignored, since it's inline*/
    margin: 0 5px 0 0;
    vertical-align: text-top;
    border: 1px solid black;
}

.filter-facet:not(.filtered)::before {
    content:'\2713';
    text-shadow: 1px 1px 1px black;
}

.filter-facet.filtered::before {
    content:'\00A0\00A0'; /*trying to outsmart it... failed =)*/
}

3) inline-block (Bootstrap 2)

Checkmark disappears with Bootstrap

Finally, to make matters worse, I'm using Bootstrap 2.3.2. When I include the CSS for Bootstrap, the checkmark disappears completely (without Bootstrap, it would show up outside of the element).

Why does the checkmark disappear?


/*
 * Using Bootstrap makes checkmark disappear
 * i.e. use the follow external resource in jsFiddle or uncomment the CSS from html HTML on SO
 * //netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css
 */

$(".filter-facet").on("click", function (e) {
    e.preventDefault();

    var $filterFacet = $(this);
    $filterFacet.toggleClass("filtered");
});
.filter-group {
    padding-top: 10px;
    padding-bottom: 5px;
    font-size: 14px;
}

.filter-label:hover {
    color: #005580;
    cursor: pointer;
}

.filter-options {
    list-style-type: none;
    margin: 0px 0px 0px 11px;
}

.filter-options.scrollable {
    max-height: 200px;
    overflow-y: auto;
}

.filter-facet {
    margin: 0;
    display: block;
    font-size: 14px;
    /* text-index + padding-left = 0,
	 * also see .filter-options input[type="checkbox"] {margin}*/
    text-indent: -19px;
    padding-left: 19px;
    cursor: pointer;
    opacity: 1.0;
}

.filter-options .count {
    font-size: smaller;
}

.filter-facet::before {
    background-color: lightblue;
    display: inline-block;
    width: 1em;
    height: 1em;
    margin: 0 5px 0 0;
    vertical-align: text-top;
    border: 1px solid black;
}

.filter-facet:not(.filtered)::before {
    content:'\2713';
    text-shadow: 1px 1px 1px black;
}

.filter-facet.filtered::before {
    content:'';
}
<!--<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet"/>-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="filter-group selected">
    <span class="filter-label">
        <span class="label-text"> Some Filter</span>
    </span>
    <ul class="filter-options scrollable">
        <li class="filter-facet"><span class="label-text">Foo 1 </span><span class="muted count">(101)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 2 </span><span class="muted count">(38)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 3 </span><span class="muted count">(38)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 4 </span><span class="muted count">(13)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 5 </span><span class="muted count">(259)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 6 </span><span class="muted count">(537)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 7 </span><span class="muted count">(21)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 8 </span><span class="muted count">(567)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 9 </span><span class="muted count">(567)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 10 </span><span class="muted count">(8)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 11 </span><span class="muted count">(192)</span></li>
    </ul>
</div>

Upvotes: 1

Views: 3242

Answers (3)

Ilya Streltsyn
Ilya Streltsyn

Reputation: 13536

1: Add the following lines to your .filter-facet::before styles:

text-indent: 0;
line-height: 1;
text-align: center;

The first line reverts the inherited from the box value of text indent to default zero, returning the text into the box. Two other lines just beautify the look by placing the character in the box center.

Edited JSfiddle example: http://jsfiddle.net/28b1tcch/3/

2: Not directly. According to the spec, width/height for inline elements are ignored. The size of inline elements depends on their font (not just font-size, but the font itself, different fonts with the same font-size may take different space). You can use monospace font which has the constant width for any character, but better is to set the display to inline-block.

Upvotes: 1

LcSalazar
LcSalazar

Reputation: 16841

Well, I'm just answering number 1 case:

The marker goes to the left because of the text identation inside the ::before element. You can easily fix it setting it's text aligment to text-align: right, so the content (tick) will be inside the square:

/*
 * Using Bootstrap makes checkmark disappear
 * i.e. use the follow external resource in jsFiddle or uncomment the CSS from html HTML on SO
 * //netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css
 */

$(".filter-facet").on("click", function (e) {
    e.preventDefault();

    var $filterFacet = $(this);
    $filterFacet.toggleClass("filtered");
});
.filter-group {
    padding-top: 10px;
    padding-bottom: 5px;
    font-size: 14px;
}

.filter-label:hover {
    color: #005580;
    cursor: pointer;
}

.filter-options {
    list-style-type: none;
    margin: 0px 0px 0px 11px;
}

.filter-options.scrollable {
    max-height: 200px;
    overflow-y: auto;
}

.filter-facet {
    margin: 0;
    display: block;
    font-size: 14px;
    /* text-index + padding-left = 0,
	 * also see .filter-options input[type="checkbox"] {margin}*/
    text-indent: -19px;
    padding-left: 19px;
    cursor: pointer;
    opacity: 1.0;
}

.filter-options .count {
    font-size: smaller;
}

.filter-facet::before {
    background-color: lightblue;
    display: inline-block;
    width: 1em;
    height: 1em;
    margin: 0 5px 0 0;
    vertical-align: text-top;
    border: 1px solid black;
}

.filter-facet:not(.filtered)::before {
    content:'\2713';
    text-shadow: 1px 1px 1px black;
    text-align: right;
}

.filter-facet.filtered::before {
    content:'';
}
<!--<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet"/>-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="filter-group selected">
    <span class="filter-label">
        <span class="label-text"> Some Filter</span>
    </span>
    <ul class="filter-options scrollable">
        <li class="filter-facet"><span class="label-text">Foo 1 </span><span class="muted count">(101)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 2 </span><span class="muted count">(38)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 3 </span><span class="muted count">(38)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 4 </span><span class="muted count">(13)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 5 </span><span class="muted count">(259)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 6 </span><span class="muted count">(537)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 7 </span><span class="muted count">(21)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 8 </span><span class="muted count">(567)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 9 </span><span class="muted count">(567)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 10 </span><span class="muted count">(8)</span></li>
        <li class="filter-facet"><span class="label-text">Foo 11 </span><span class="muted count">(192)</span></li>
    </ul>
</div>

Upvotes: 1

Suresh Karia
Suresh Karia

Reputation: 18228

Its because text indent in .filter-facet class

.filter-facet {
    margin: 0;
    display: block;
    font-size: 14px;
    /* text-index + padding-left = 0,
     * also see .filter-options input[type="checkbox"] {margin}*/
    text-indent: -19px; /* Remove this css rule */
    padding-left: 19px;
    cursor: pointer;
    opacity: 1.0;
}

this is screenshot

enter image description here

Upvotes: 1

Related Questions