Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Option to change the default CSS options #677

Closed
imolorhe opened this issue Feb 10, 2014 · 21 comments
Closed

Add Option to change the default CSS options #677

imolorhe opened this issue Feb 10, 2014 · 21 comments
Milestone

Comments

@imolorhe
Copy link

I am currently working on a project and decided to use typahead.js in it. It works fine so far. However, there are instances where the default CSS values used don't work well for me (especially the absolute positioning). There should be a way to override these values.

@roylines
Copy link

I have the same request - positioning is causing us issues as it's hard to override when the options are inline. I've taken a fork and will have a go at passing some options in. I've read the contributing guidelines, but is there any approach you'd prefer me to take?

@imolorhe
Copy link
Author

To override it, just add the styles in your css files using the !important override feature. Works for me. At least for the meantime.

@roylines
Copy link

That's a great idea - thanks.

I'm going to take a look at the code to see how hard it would be for typeahead to take an option that removes all inline css. You would, of course, then have to deal with it in your own css, but I think that would work well for me. Is that something that would help you too, or do you have a better suggestion?

@imolorhe
Copy link
Author

Yeah...definitely!

@ragulka
Copy link
Contributor

ragulka commented Mar 6, 2014

I also support this request. jQuery UI autocomplete allows you to completely override the positioning of the suggestion menu and I'd love to see something similar with typeahead.

For example - when I want to set the suggestion menu width equal to the original input, I can't do it. Compare Autocomplete vs Typeahead here http://sliptree.github.io/bootstrap-tokenfield/ to see what I mean.

@jharding
Copy link
Contributor

jharding commented Mar 8, 2014

Any proposals on how this should be enabled? Just accept a css option that overrides this?

@ragulka
Copy link
Contributor

ragulka commented Mar 9, 2014

@jharding Would that work if the position would have to be calculated on the fly? For example, in response to browser window resize events?

@jharding
Copy link
Contributor

jharding commented Mar 9, 2014

Nope, that's why I'm not a huge fan of the idea – it doesn't add anything you couldn't accomplish with the !important rule.

@ragulka, btw, I'm getting some 404s for assets over at http://sliptree.github.io/bootstrap-tokenfield/.

@jamesleebaker
Copy link

No intention to troll....but the !important rule should be avoided as much as possible. By using this, you're telling every developer that your rules are the only rules that will have the highest CSS Specificity...ever.

The only correct use case of CSS !important is when your control has certain default rules that shouldn't never be modified and, in this case, the control author should use the !important keyword, not the consuming developer. (see http://css-tricks.com/when-using-important-is-the-right-choice/)

Like many above, the introduction of this plugin into my UI ecosystem has caused much pain and forces me to override my styles.

Proposal
It would be nice to have a className param to pass into the options of the typeahead that I can use; I would rather not have twitter's naming conventions in my UI if I can avoid this (the same would go for any plugin). Ideally, having author-agnostic classnames would be ideal (i.e. .typeahead, .typeahead-suggestions, .suggestion-item, etc.).

With this, it would also be great to avoid too much inline CSS through JavaScript. By combining a className attribute with reducing inline CSS through JavaScript, developers can have more control over their CSS.

@ragulka
Copy link
Contributor

ragulka commented Mar 10, 2014

FWIW, I tend to agree with @jamesleebaker on the use of !important. Personally, I always get frustrated when I have to fall back to !important to override some plugin/library styles.

Actually, that raises a question - why doesn't typeahead simply come with a stylesheet that takes care of the styling?

Another option that could work: allow using events to overwrite the css properties set by typeahead.js after they have been set.

@jharding, thanks - fixed those.

@jamesleebaker
Copy link

@ragulka You bring up a good question. There are certain styles that this plugin would need in order to function correctly, which explains the author's reasoning for placing styles inline.. For example, the transparent background for the .tt-input in order to show the hints of .tt-hint, or the width, height, and font dimensions being similar in order to properly show the hint.

One thing i've done in the past to get around this is to have two portions of my external CSS file - a base set of styles that should not be modified (but can if need be) by the developer. It is here I can place !important keywords to enforce that the author styles are as final to maintain functionality. This ensures the plugin is functional and minimally skinned out of the box. The second set of styles would be within the stylesheet and would use the natural effect of cascading to add the 'skin' to the plugin; this can be unique to the defaults of the plugin and completely customizable by the consuming developer. If the developer runs into a scenario where the base styles are causing grief, they can alter those styles without affecting the plugin itself.

This solution would eliminate any JS CSS and any need to override through config settings as well. Yes, the developer has more control over breaking the plugin by using this approach, however, a couple clear lines in documentation and on a readme can be sufficient to clarify.

@jharding
Copy link
Contributor

No intention to troll....but the !important rule should be avoided as much as possible. By using this, you're telling every developer that your rules are the only rules that will have the highest CSS Specificity...ever.

I completely agree with this, but since typeahead.js applies styling inline, the !important rule is unfortunately necessary.

It would be nice to have a className param to pass into the options of the typeahead that I can use; I would rather not have twitter's naming conventions in my UI if I can avoid this (the same would go for any plugin). Ideally, having author-agnostic classnames would be ideal (i.e. .typeahead, .typeahead-suggestions, .suggestion-item, etc.).

Great idea, I'd definitely be ok with supporting something like this.

Actually, that raises a question - why doesn't typeahead simply come with a stylesheet that takes care of the styling?

It originally did. There were 2 reasons why I switched to using inline styles: 1) dropped the dependency on additional CSS which made it easier to get started with typeahead.js IMO and 2) I felt the styles typeahead.js was applying were essential to the typeahead working correctly so I wanted to make sure they weren't easy to override.

In hindsight, I'm not sure that was the best decision and maybe it's time the decision was reevaluated. v0.10.2 is about to ship and the focus of v0.10.3 is going to be on improving custom events, but for v0.10.4 I'd like to work on the stuff mentioned in this issue.

@jharding jharding added this to the v0.10.4 milestone Mar 10, 2014
@grifx
Copy link

grifx commented Jun 27, 2014

Is it implemented now @jharding ?

@jharding
Copy link
Contributor

For those of you following along at home, I'll be spending the weekend focusing on this issue (and others related to this one). Here's the direction I'm thinking about heading in:

I'll add support for hint and menu options in the options hash for the jQuery plugin. These options would allow developers to pass in ready-made DOM elements for the hint and dropdown menu. No inline styles would be applied to these elements. If a developer doesn't use hint or menu it'll default to the current behavior where elements are created and injected into the page with inline styles. IMO this approach offers maximum flexibility while still making it easy to get started with typeahead.js out of the box.

Oh, and I'll also add support for adding custom classes to the elements generated by the plugin. That should be pretty straightforward.

If anyone has any opinions, please share. All feedback is good feedback.

@ChrisMissal
Copy link

FWIW I'm a fan of overriding css properties. Since the default is:

dropdown: {
    position: "absolute",
    top: "100%",
    left: "0",
    zIndex: "100",
    display: "none"
},

That value would be used unless options specified a new css.dropdown value, in which case, that would be used:

$dropdown = $(html.dropdown).css(opCss.dropdown || css.dropdown);

This means that buildDom would have to change to allow those overrides to be passed in, but it seems fairly seamless.

Update: Actually, what you're proposing @jharding, might make my suggestion pointless. It sounds like the flexibility you mentioned could eliminate the change I suggested, yes?

@jharding
Copy link
Contributor

Actually, what you're proposing @jharding, might make my suggestion pointless. It sounds like the flexibility you mentioned could eliminate the change I suggested, yes?

Yeah, it seems that way. Rather than passing in css overrides, you would just pass in a DOM element that should be used as the dropdown menu and typeahead.js won't apply any style changes. Check out #902 for the branch that introduces this change.

@ChrisMissal
Copy link

Check out #902 for the branch that introduces this change.

Will do, thanks!

@jjt
Copy link

jjt commented Jul 30, 2014

Somewhat related, I'm trying to style the input element with a different background if a choice has been made, but the inline style on the input of background: transparent is forcing me to resort to !important in my CSS. I feel the same way as @jamesleebaker on its usage, but I'm guessing that's just how it's gotta be.

@jharding jharding modified the milestones: DOM and Style Customization, v0.11.0 Aug 15, 2014
@just-boris
Copy link

+1 looking forward this option as far as I use the lib

@afirdousi
Copy link

I have a similar request for my situation. One a single text box, I show 3 types of suggestions. When the user selects from suggestion for the first time, a new request is made for different collection and then I show it again in type-ahead...the 3rd time type ahead appears the same way. The problem is user can also do a backspace at the 2nd or 3rd type-ahead appearance, what happens is dynamically it changes the collection to give appropriate suggestion but the position , the absolute position of suggestions remain the old one...Once the user starts typing it goes back to normal..

Any idea how to manipulate with the $position factory injected in typeahead directive.

@maggiben
Copy link

This is as bad as it gets, I had to resort to this "awful" css to get my typeahead component display the suggestion menu to the right.

  right: 0px !important;
  left: -100% !important;

...It originally did. There were 2 reasons why I switched to using inline styles: 1) dropped the dependency on additional CSS which made it easier to get started with typeahead.js IMO and 2) I felt the styles typeahead.js was applying were essential to the typeahead working correctly so I wanted to make sure they weren't easy to override.

Chances are you're going to write custom css to style the component to meet your design rules, so bottom line is, additional css is guaranteed to be needed.
On the other hand, while the menu container is absolutely positioned it does so relative to it's parent not the entire viewport, there is no necessity to fiddle around absolute x&y coordinates... (unless you're in a modal and the dropdown menu is appended to the <body> a feature that typeahead does not support btw...)
We're just talking about left, right, top and bottom positioning, just like every other dropdown menu out there... An ideal solution should allow some degree of customization either by optional arguments in the javascript or css...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests