Twitter's typeahead.js suggestions are not styled (have no border, transparent background, etc.)
Asked Answered
M

11

187

I'm using twitter's typeahead.js 0.9.3 and it seems my suggestions are not styled at all.

I'm getting this:

typeahead bug

Instead of something like this: (taken from examples page)

typehead ideal

JavaScript enabling typeahead:

$('.search-typeahead').typeahead({
    name: 'videos',
    remote: {
        url: '/api/v1/internal/videos/typeahead?text=%QUERY'
    }
});

HTML input element:

<input type="text" value="" id="search_keywords" class="no-clear search-typeahead"/>

Additional Notes:

The site I'm working on has jQuery 1.10.1 and does not use twitter bootstrap. There is a bunch of CSS that I didn't write and thus am not familiar with which I fear is interfering, however it seems the plugin adds its own styles (there is no accompanying .css file) so shouldn't it theoretically override things? I'm confused why my styles work, but those added by the plugin do not, resulting in an suggestions with transparent backgrounds, no borders, etc.

Mikimikihisa answered 25/11, 2013 at 16:36 Comment(0)
M
220

So looking into the docs I now see:

By default, the dropdown menu created by typeahead.js is going to look ugly and you'll want to style it to ensure it fits into the theme of your web page.

My solution was thus to copy the styling from the example I wished to replicate:

.tt-query, /* UPDATE: newer versions use tt-input instead of tt-query */
.tt-hint {
    width: 396px;
    height: 30px;
    padding: 8px 12px;
    font-size: 24px;
    line-height: 30px;
    border: 2px solid #ccc;
    border-radius: 8px;
    outline: none;
}

.tt-query { /* UPDATE: newer versions use tt-input instead of tt-query */
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}

.tt-hint {
    color: #999;
}

.tt-menu { /* UPDATE: newer versions use tt-menu instead of tt-dropdown-menu */
    width: 422px;
    margin-top: 12px;
    padding: 8px 0;
    background-color: #fff;
    border: 1px solid #ccc;
    border: 1px solid rgba(0, 0, 0, 0.2);
    border-radius: 8px;
    box-shadow: 0 5px 10px rgba(0,0,0,.2);
    max-height: 300px;
    overflow-y: auto;
}

.tt-suggestion {
    padding: 3px 20px;
    font-size: 18px;
    line-height: 24px;
}

.tt-suggestion.tt-is-under-cursor { /* UPDATE: newer versions use .tt-suggestion.tt-cursor */
    color: #fff;
    background-color: #0097cf;

}

.tt-suggestion p {
    margin: 0;
}
Mikimikihisa answered 25/11, 2013 at 23:27 Comment(10)
For some reason my suggested edit got rejected, but note that the tt-is-under-cursor class seems to have been renamed to tt-cursor. Documentation here.Whelm
There is also a tt-input instead of the tt-query (as for 0.10.5)Abbyabbye
Thanks @FilipSpiridonov, I've edited the answer to add comments for that as well.Mikimikihisa
Wouldn't it be better to have the old versions in the comments?Justis
.tt-dropdown-menu is now .tt-menuLankester
What's up with tt-menu's double entry for 'border'?Hostetter
Add cursor: pointer; to .tt-is-under-cursor to have a proper cursor that tells the user that he needs to click.Fact
Thanks! that worked but to prevent horizontal scrollbar and data over flow: tt-menu { max-height: 200px; overflow-y: auto; /* prevent horizontal scrollbar */ overflow-x: hidden; }Bloomer
I would also add the mouse-over highlighting to make this answer perfect: .tt-suggestion.tt-cursor,.tt-suggestion:hover { color: #fff; background-color: #0097cf; }Orangewood
I added max-height and overflow-y to the .tt-menu style to create a scrolling menu.Diskin
Q
131

So, the following styles will give you this look & feel. It's based on the CSS I extracted from the official Typeahead examples website.

enter image description here

CSS:

.tt-query {
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}

.tt-hint {
  color: #999
}

.tt-menu {    /* used to be tt-dropdown-menu in older versions */
  width: 422px;
  margin-top: 4px;
  padding: 4px 0;
  background-color: #fff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.2);
  -webkit-border-radius: 4px;
     -moz-border-radius: 4px;
          border-radius: 4px;
  -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
     -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
          box-shadow: 0 5px 10px rgba(0,0,0,.2);
}

.tt-suggestion {
  padding: 3px 20px;
  line-height: 24px;
}

.tt-suggestion.tt-cursor,.tt-suggestion:hover {
  color: #fff;
  background-color: #0097cf;

}

.tt-suggestion p {
  margin: 0;
}

This assumes your input will have the form-control class. For my example, it's like this:

<input class="typeahead form-control" type="text" placeholder="States of USA">
Quadrivium answered 14/11, 2014 at 16:17 Comment(1)
Worked for me with one tweak. Appears .tt-dropdown-menu is now .tt-menu. Thanks for answer.Lynseylynus
P
35

https://github.com/bassjobsen/typeahead.js-bootstrap-css/blob/master/typeaheadjs.css

The other ones didn't look great, this one looks most like Bootstrap.

Pasteup answered 7/10, 2014 at 9:45 Comment(3)
Works great with BootstrapKenyettakenyon
This worked perfectly with no changes in Rails 4.2 and bootstrap-sass (3.3.7) autoprefixer-rails (>= 5.2.1) sass (>= 3.3.4) It's also a bit more responsive friendly that some of the other solutions. Plus it means your input box can be width 100% so should work with most layouts.Timmi
Although if you input is wider than 162 (the min width used here) then you might want to also add width: 100%; to the first section for the tt-menu/tt-dropdownTimmi
D
19

Typeahead has changed some of their class names and the above examples are now incorrect.

For instance:

  • Instead of .tt-suggestion.tt-is-under-cursor use .tt-suggestion:hover
  • Instead of .tt-dropdown-menu, use .tt-menu

If you want to borrow the style from the examples page, you can see their stylesheet here:

.typeahead,
.tt-query,
.tt-hint {
  width: 396px;
  height: 30px;
  padding: 8px 12px;
  font-size: 24px;
  line-height: 30px;
  border: 2px solid #ccc;
  -webkit-border-radius: 8px;
     -moz-border-radius: 8px;
          border-radius: 8px;
  outline: none;
}

.typeahead {
  background-color: #fff;
}

.typeahead:focus {
  border: 2px solid #0097cf;
}

.tt-query {
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}

.tt-hint {
  color: #999
}

.tt-menu {
  width: 422px;
  margin: 12px 0;
  padding: 8px 0;
  background-color: #fff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.2);
  -webkit-border-radius: 8px;
     -moz-border-radius: 8px;
          border-radius: 8px;
  -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
     -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
          box-shadow: 0 5px 10px rgba(0,0,0,.2);
}

.tt-suggestion {
  padding: 3px 20px;
  font-size: 18px;
  line-height: 24px;
}

.tt-suggestion:hover {
  cursor: pointer;
  color: #fff;
  background-color: #0097cf;
}

.tt-suggestion.tt-cursor {
  color: #fff;
  background-color: #0097cf;

}

.tt-suggestion p {
  margin: 0;
}

Here's a Demo in Stack Snippets

var substringMatcher = function(strs) {
  return function findMatches(q, cb) {
    var matches, substringRegex;
 
    // an array that will be populated with substring matches
    matches = [];
 
    // regex used to determine if a string contains the substring `q`
    substrRegex = new RegExp(q, 'i');
 
    // iterate through the pool of strings and for any string that
    // contains the substring `q`, add it to the `matches` array
    $.each(strs, function(i, str) {
      if (substrRegex.test(str)) {
        matches.push(str);
      }
    });
 
    cb(matches);
  };
};
 
var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
  'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
  'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
  'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
  'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
  'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
  'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
  'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
  'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
];
 
$('.typeahead').typeahead({
  hint: true,
  highlight: true,
  minLength: 1
},
{
  name: 'states',
  source: substringMatcher(states)
});
.typeahead,
.tt-query,
.tt-hint {
  width: 396px;
  height: 30px;
  padding: 8px 12px;
  font-size: 24px;
  line-height: 30px;
  border: 2px solid #ccc;
  -webkit-border-radius: 8px;
     -moz-border-radius: 8px;
          border-radius: 8px;
  outline: none;
}

.typeahead {
  background-color: #fff;
}

.typeahead:focus {
  border: 2px solid #0097cf;
}

.tt-query {
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}

.tt-hint {
  color: #999
}

.tt-menu {
  width: 422px;
  margin: 12px 0;
  padding: 8px 0;
  background-color: #fff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.2);
  -webkit-border-radius: 8px;
     -moz-border-radius: 8px;
          border-radius: 8px;
  -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
     -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
          box-shadow: 0 5px 10px rgba(0,0,0,.2);
}

.tt-suggestion {
  padding: 3px 20px;
  font-size: 18px;
  line-height: 24px;
}

.tt-suggestion:hover {
  cursor: pointer;
  color: #fff;
  background-color: #0097cf;
}

.tt-suggestion.tt-cursor {
  color: #fff;
  background-color: #0097cf;

}

.tt-suggestion p {
  margin: 0;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet"/>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.jquery.js"></script>


<div class="container" >
  <input class="typeahead form-control" type="text" placeholder="States of USA" />
</div>
Dustproof answered 7/7, 2015 at 20:24 Comment(1)
Is it possible to prevent typeahead making the width so small?Arabic
Q
13

This is the code that works for me:

.twitter-typeahead .tt-query,
.twitter-typeahead .tt-hint {
    margin-bottom: 0;
}
.tt-hint {
    display: block;
    width: 100%;
    padding: 8px 12px;
    font-size: 14px;
    line-height: 1.428571429;
    color: #999;
    vertical-align: middle;
    background-color: #ffffff;
    border: 1px solid #cccccc;
    border-radius: 4px;
    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
    -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
          transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
}
.tt-dropdown-menu {
    min-width: 160px;
    margin-top: 2px;
    padding: 5px 0;
    background-color: #ffffff;
    border: 1px solid #cccccc;
    border: 1px solid rgba(0, 0, 0, 0.15);
    border-radius: 4px;
    -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
          box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
    background-clip: padding-box;

}
.tt-suggestion {
    display: block;
    padding: 3px 20px;
}
.tt-suggestion.tt-is-under-cursor {
    color: #fff;
    background-color: #dfdfdf;
}
.tt-suggestion.tt-is-under-cursor a {
    color: #fff;
}
.tt-suggestion p {
    margin: 0;
}
Quadrivium answered 28/6, 2014 at 14:35 Comment(2)
This solution works no matter the width of the input. Thanks!Cown
Work perfect for me with typeahead.js + BS3 + datatable on the same screen . ThanksHow
S
3

Since i have a less environment with BS3 included i took Zugwalt css code (placed it in a more readable hierarchy) and filled it with styling from bs3's dropdown-menu. It's simply following your (customized) variables.

    .twitter-typeahead {
      display: block;
      width: 100%; //BS 3 needs this to inherit this for children

      .tt-query,
      .tt-hint {
        margin-bottom: 0;
      }

      .tt-dropdown-menu {
        z-index: @zindex-dropdown;
        min-width: 326px;
        padding: 5px 0;
        margin: 2px 0 0; // override default ul
        font-size: @font-size-base;
        text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
        background-color: @dropdown-bg;
        border: 1px solid @dropdown-fallback-border; // IE8 fallback
        border: 1px solid @dropdown-border;
        border-radius: @border-radius-base;
        .box-shadow(0 6px 12px rgba(0, 0, 0, .175));
        background-clip: padding-box;

        .tt-suggestions {

          .tt-suggestion {
            padding: 3px 12px;
            font-weight: normal;
            line-height: @line-height-base;
            color: @dropdown-link-color;
            white-space: nowrap; // prevent links from randomly breaking onto new lines
          }

          .tt-suggestion.tt-cursor {
            color: @dropdown-link-hover-color;
            background-color: @dropdown-link-hover-bg;
          }

          .tt-suggestion p {
            margin: 0;
          }
        }
      }
    }
Solubility answered 18/11, 2014 at 22:36 Comment(0)
N
1

Here's an scss version that relies on the bootstrap variables/declarations as much as possible. Unfortunately you cannot extend nested selectors in sass, otherwise it would be smaller:

@mixin typeahead-active() {
  // mimics  @extend .dropdown-menu > .active > a;
  color: $dropdown-link-active-color;
  text-decoration: none;
  outline: 0;
  background-color: $dropdown-link-active-bg;
}

//https://github.com/corejavascript/typeahead.js/blob/master/doc/jquery_typeahead.md#class-names
span.twitter-typeahead {

  // this is the suggested matches dropdown
  .tt-menu {
    @extend .dropdown-menu;
  }

  .tt-hint {
    color: #999
  }

  // Added to suggestion elements.
  .tt-suggestion {

    // mimic .dropdown-menu > li > a
    padding: 3px 20px;
    line-height: $line-height-base;

    // Added to suggestion element when menu cursor moves to said suggestion.
    &.tt-cursor {
      @include typeahead-active;
    }

    // Hover/focus on suggestion
    &:hover,
    &:focus {
      @include typeahead-active;
    }

    p {
      margin: 0;
    }
  }

  .input-group & {
    display: block !important;
    .tt-dropdown-menu {
      top: 32px !important;
    }
  }
  .input-group.input-group-lg & {
    .tt-dropdown-menu {
      top: 44px !important;
    }
  }
  .input-group.input-group-sm & {
    .tt-dropdown-menu {
      top: 28px !important;
    }
  }
}
Niklaus answered 16/10, 2015 at 18:34 Comment(0)
M
1

If you are using Bootstrap 4, it's enough to do this:

span.twitter-typeahead
  width: 100%

.tt-input
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075)

.tt-menu
  @extend .list-group
  box-shadow: 0 5px 10px rgba(0,0,0,.2)
  width: 100%

.tt-suggestion
  @extend .list-group-item

.tt-selectable
  @extend .list-group-item-action
Moffit answered 30/6, 2018 at 20:47 Comment(0)
B
0

In my particular case absolute positioning solved it. Relative positioning was pushing down other bootstrap elements when the suggestion list (tt-menu) was open.

.tt-menu { 
    z-index: 2147483647;
    position: absolute;    
}

You can add this to the above answer https://mcmap.net/q/135199/-twitter-39-s-typeahead-js-suggestions-are-not-styled-have-no-border-transparent-background-etc

Barratry answered 8/1, 2019 at 19:29 Comment(0)
D
0

What worked for me:

.typeahead, .twitter-typeahead, .tt-hint, .tt-input, .tt-menu { width: 100%; height:auto; }

Adding height:auto; especially in "tt-hint".

Debenture answered 13/1, 2021 at 22:44 Comment(0)
C
0

Another way to get the styling is after going to the typeahead website, select see examples below the large search bar then type a letter on any of the suggestion boxes for the examples.

From there, right-click on one of the suggestions that show up under the search bar and choose "View page source". This shows you all the HTML, CSS, and JS used. At the very top of the HTML you now see, click on the link to the stylesheet.

<link rel="stylesheet" href="../css/examples.css">

This shows you all the CSS used.

The following chunk of code helped me out, but you're free to use as much of it as you want.

.typeahead {
  background-color: #fff;
}

.typeahead:focus {
  border: 2px solid #0097cf;
}

.tt-query {
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}

.tt-hint {
  color: #999
}

.tt-menu {
  width: 422px;
  margin: 12px 0;
  padding: 8px 0;
  background-color: #fff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.2);
  -webkit-border-radius: 8px;
     -moz-border-radius: 8px;
          border-radius: 8px;
  -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
     -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
          box-shadow: 0 5px 10px rgba(0,0,0,.2);
}

.tt-suggestion {
  padding: 3px 20px;
  font-size: 18px;
  line-height: 24px;
}

.tt-suggestion:hover {
  cursor: pointer;
  color: #fff;
  background-color: #0097cf;
}

.tt-suggestion.tt-cursor {
  color: #fff;
  background-color: #0097cf;

}

.tt-suggestion p {
  margin: 0;
}

TLDR: https://twitter.github.io/typeahead.js/css/examples.css

Cleary answered 13/6, 2021 at 13:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.