Tom-select with bootstrap 5 theme differs visually from bootstrap 5.1.3 styled select

4.2k views Asked by At

Premise

In order to display selects the same on Windows, Linux and Mac, in my project, i am using combination of:

I have set up SCSS files of bootstrap and tom-select.

Frontend packages are managed by Yarn package manager.

I work with SCSS because i am overriding Bootstrap variables with custom sets for different themes inside the site.

My working configuration with Symfony and Webpack Encore has SCSS and JS separated (CSS is not included in JavaScript). CSS is compiled from SCSS that includes tom-select SCSS.

Webpage includes CSS (Bootstrap + theme customizations + tom-select) and JS (bootstrap and tom-select separately).

Problem

  1. Select shows with smaller than default in bootstrap 5 box-shadow around its field.
  2. Select element has +2px height when compared with default in bootstrap 5
  3. Select element dropdown starts farther away from its field when compared with default in bootstrap 5

Number 2 and 3 are mild inconveniences, but 1-st one i consider a problem.

Illustration

screenshot of input and tom-select fields in Firefox

Things i tried

  1. Redefine tom-select variable $input-focus-width, but it did not succeed;
  2. Tried different arrangement of includes in SCSS main override (those configurations that worked still exposed the problem at hand);
  3. Introduced additional CSS rules (see Update 1)

Code

main override SCSS

@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";

$input-border-color: $gray-500;
$form-select-border-color: $gray-500;
$input-group-addon-border-color: $gray-500;
$input-focus-width: 0.25rem; /* no effect on tom-select */

@import "~bootstrap/scss/bootstrap";
@import "~tom-select/src/scss/tom-select.bootstrap5";

main SCSS imports override

@import "./main_override";

body
{
    background: #f0ede8 !important;
}

/* other styles follow */

TWIG template (page that includes compiled CSS)

{% extends 'base_admin.html.twig' %}

{% block title %}New firm{% endblock %}

{% block stylesheets %}
    {{ parent() }}
{% endblock %}

{% block javascripts %}
    {{ parent() }}

    {{ encore_entry_script_tags('tom_select') }}
{% endblock %}

{% block main_content %}
    <div class="wrapper">
        <h3 class="fix text-center">{% trans from 'menu' %}menu.firm.new{% endtrans %}</h3>

        <div class="container">
            <div class="inner-container">
                <div class="box-list clearfix">
                    {% if form is defined %}
                        {{ form_start(form, {'attr': {'id': 'form-firm-create', 'novalidate': 'novalidate', 'autocomplete': 'off'}, 'method': 'POST'}) }}
                            <div class="field-group">
                                {{ form_row(form.isSpecial, {'label_attr': {'class': 'form-group-label'}, 'attr': {'class': 'form-control'}}) }}
                            </div>
                            <div class="box-btn form-group text-center box-submit">
                                <a class="btn btn-secondary me-1" href="{{ path('firm_list') }}">
                                    <i class="fas fa-long-arrow-left"></i>
                                    <span>{%- trans from 'firms' %}firms.goToList{% endtrans -%}</span>
                                </a>
                                {{ form_widget(form.firmCreate) }}
                            </div>
                        {{ form_end(form) }}
                    {% endif %}
                </div>
            </div>
        </div>
    </div>
{% endblock %}

JavaScript that is executed on page

"use strict";

import TomSelect from "tom-select/dist/js/tom-select.complete.min.js";

$(function()
{
    new TomSelect("#firm_create_isSpecial", {
        allowEmpty: false,
        create: false,
        sortField: {
            direction: "asc",
            field: "text"
        }
    });
});

Conclusion

What i am doing wrong?

Is there an error in my config?

Thank you for ideas and suggestions.

Update 1

With the following rules added i got same width box-shadow and correct inner border color, yet there is a flash when clicking on select because of field's width increase by 2px in order to get right width of control.

Added CSS rules

.ts-wrapper.form-select .ts-control,
.ts-wrapper.form-select.focus .ts-control
{
    border: 1px solid #fff !important;
}

.ts-wrapper.form-select.single.input-active .ts-control
{
    border: 1px solid #ccc !important;
}
.ts-wrapper.form-select.single.input-active.focus .ts-control
{
    border: 1px solid #86b7fe !important;
}

.my-ts-select.focus .ts-control,
.my-ts-select:focus .ts-control
{
    border: 1px solid #86b7fe !important;
    box-shadow: 0 0 0 .25rem #b7d5ff !important;
    outline: 0;
    width: calc(100% + 2px);
    margin-left: -1px;
}

.ts-control
{
    border: none !important;
}

I imagine that provided CSS rules can be optimized. Do not hesitate to provide your suggestions.

Update 2

Tried some more modifications to CSS and discovered that removing class: form-select from rendered field makes tom-select control to conform to bootstrap styling (without additional styling)!

2

There are 2 answers

0
Rikijs On

In order to get tom-select to display itself in Bootstrap styling Use JavaScript to remove class 'form-select' before setting up the field.

"use strict";

import TomSelect from "tom-select/dist/js/tom-select.complete.min.js";

window.addEventListener('load', (event) =>
{
    // remove form-select class from tom-select element
    document.getElementById("test_is_special").classList.remove('form-select');

    // initialize tom-select
    new TomSelect("#test_is_special", {
        allowEmpty: false,
        create: false,
        sortField: {
            direction: "asc",
            field: "text"
        }
    });
});
0
Justin Tanner On

I noticed the same problem using tom-select version 2.0.1.

After upgrading the JS and CSS to version 2.0.3 this problem is now fixed.

I can use form-control and even form-control-sm and it matches other inputs and selects in BS5.