Using the CSS :after pseudo-selector to display directional carets in Bootstrap 3 input-groups

10,395

It seems .input-group > input + span:before will be a good selector for Right Aligned. But there will also be the problem that box-sizing : border-box (Why did Bootstrap 3 switch to box-sizing: border-box?) breaks the carets / forms. (width include :after and :before too?)

see: http://bootply.com/83702

.input-group > input + span:before {
  display: inline-block;
  width: 0;
  height: 0;
  border-right: 10px solid red;
  border-top: 10px solid transparent;
  border-left: 0 dotted;
  border-bottom: 10px solid transparent;

  vertical-align: middle;
  margin-left: 2px;
  content:'';
}
Share:
10,395
Karl Offenberger
Author by

Karl Offenberger

Updated on June 30, 2022

Comments

  • Karl Offenberger
    Karl Offenberger almost 2 years

    I've been trying to apply carets to input-group elements in Bootstrap 3. Failing so far. Tried using table-cell display for the inserted pseudo element, tried absolute positioning, tried using the content property to display a web font caret instead of my preferred CSS triangle caret. Just can't wrap my head around this one.

    Here's a JSFiddle (the red borders being where I'd expect the caret to show).

    .input-group .input-group-addon:last-child:before,
    .input-group .input-group-btn:last-child:before,
    .input-group .input-group-addon:not(:last-child):before,
    .input-group .input-group-btn:not(:last-child):before {
      position: absolute;
      content: '';
      width: 0;
      height: 0;
      border: 10px solid transparent;
      margin: auto;
      top: 0;
      bottom: 0;
      z-index: 1000;
    }
    
    .input-group .input-group-addon:last-child:before,
    .input-group .input-group-btn:last-child:before {
      border-right-color: red;
      right: 0;
    }
    
    .input-group .input-group-addon:not(:last-child):before,
    .input-group .input-group-btn:not(:last-child):before {
      border-left-color: red;
      left: 0;
    }
    

    EDIT : Based on an answer, I modified the styles which now work fine in all but IE10 and below. IE offsets left-aligned input-group carets by 4px as can be seen here http://jsfiddle.net/W8mFS/3/. Any ideas how to fix this up?

    The updated CSS:

    .input-group.input-group-caret span:after,
    .input-group.input-group-caret > input + span:before {
      position: absolute;
      content: '';
      width: 0;
      height: 0;
      top: 0;
      bottom: 0;
      margin: auto;
      border: 10px solid transparent;
    }
    
    .input-group.input-group-caret > input + span:before {
      border-right-color: #cccccc;
      margin-left: -20px;
    }
    
    .input-group.input-group-caret > input + span:empty:before {
      margin-left: -44px;
    }
    
    .input-group.input-group-caret > input + span:after {
      border-left-color: transparent;
    }
    
    .input-group.input-group-caret span:after {
      border-left-color: #cccccc;
    }
    
    .input-group.input-group-caret .input-group-addon {
      padding: 0;
    }
    
    .input-group.input-group-caret .input-group-addon i {
      font-style: normal;
      margin-left: 12px;
      padding-right: 12px;
    }
    
    .input-group.input-group-caret .input-group-addon:empty {
      padding-left: 24px;
    }
    

    UPDATE : With added input-group sizing JSFiddle here: http://jsfiddle.net/W8mFS/4/.

    The LESS code shows the use of Bootstrap variables to control caret size, margins and padding:

    @import "path_to_bootstrap/less/mixins";
    @import "path_to_bootstrap/less/variables";
    
    // input-group caret size
    @caret-size-base:  ceil(@font-size-base * 0.70);  // ~10px;
    @caret-size-large: ceil(@caret-size-base * 1.20); // ~12px;
    @caret-size-small: ceil(@caret-size-base * 0.80); // ~8px;
    
    // input-group caret
    .input-group.input-group-caret {
      span:after,
      > input + span:before {
        position: absolute;
        content: '';
        width: 0;
        height: 0;
    
        // v-align to middle
        top: 0;
        bottom: 0;
        margin: auto;
    
        border: @caret-size-base solid transparent;
      }
    
      > input + span:before { border-right-color: @input-border; margin-left: -( 2 * @caret-size-base ); }                  // right aligned
      > input + span:empty:before { margin-left: -(( 2 * @padding-base-horizontal ) + ( 2 * @caret-size-base )); }          // right aligned
      > input + span:after  { border-left-color: transparent; }                                                             // right aligned
      span:after  { border-left-color: @input-border; }                                                                     // left aligned
    
      // sizing
      &.input-group-sm {
        span:after,
        > input + span:before {
          border: @caret-size-small solid transparent;
        }
    
        > input + span:before { border-right-color: @input-border; margin-left: -( 2 * @caret-size-small ); }               // right aligned
        > input + span:empty:before { margin-left: -(( 2 * @padding-base-horizontal ) + ( 2 * @caret-size-small )); }       // right aligned
        > input + span:after  { border-left-color: transparent; }                                                           // right aligned
        span:after  { border-left-color: @input-border; }                                                                   // left aligned
      }
    
      &.input-group-lg {
        span:after,
        > input + span:before {
          border: @caret-size-large solid transparent;
        }
    
        > input + span:before { border-right-color: @input-border; margin-left: -( 2 * @caret-size-large ); }               // right aligned
        > input + span:empty:before { margin-left: -(( 2 * @padding-base-horizontal ) + ( 2 * @caret-size-large )); }       // right aligned
        > input + span:after  { border-left-color: transparent; }                                                           // right aligned
        span:after  { border-left-color: @input-border; }                                                                   // left aligned
      }
    
      // input-group caret alignment fixes
      .input-group-addon {
        padding: 0;
    
        i {
          font-style: normal;
          margin-left: @padding-base-horizontal;
          padding-right: @padding-base-horizontal;
        }
    
        // fix-up alignment of empty addon
        &:empty {
          padding-left: 2 * @padding-base-horizontal;
        }
      }
    }