Search code examples
cssreactjsfrontendtailwind-cssstyling

Text overflow ellipses are not showing, instead text just hidden


I am trying to add tabs to an app. The tabs get smaller the more I add, how the tab text is just hidden instead of showing ellipses. Can anyone help? enter image description here enter image description here


const Tabs: React.FC = () => {
  const [tabs, setTabs] = useState(["Tab 1"]);

  const addNewTab = () => {
    setTabs([...tabs, `Tab ${tabs.length + 1}`]);
  };

  return (
    // outer div ensures that the tabs take up the remaining space in whatever view we use
    <div className="flex-1 overflow-hidden">
      <div className="flex overflow-hidden items-center h-8">
        {tabs.map((tab, index) => (
          //  outer div so that when you hover over tab, it does not colour all the way to tab border
          <div
            key={index}
            className="flex basis-40 justify-center items-center h-8 border-r px-1 border-gray-300 whitespace-nowrap overflow-hidden text-ellipsis"
          >
            <div
              className="h-7 basis-36 flex items-center text-sm hover:bg-slate-300 rounded"
              title={tab}
            >
              {tab}
            </div>
          </div>
        ))}
        {/* add styling to button to ensure */}
        <button
          className="ml-2 hover:bg-slate-300 rounded flex items-center justify-center h-7 w-7 flex-shrink-0"
          onClick={addNewTab}
        >
          <img src={AddIcon} alt="Add icon" className="h-5 w-5" />
        </button>
      </div>
    </div>
  );
};

export default Tabs;

Solution

  • The text truncation does not work in a flex layout context. You'd need to wrap the text in a non-flex layout and have the classes applied to that, like:

    <span class="whitespace-nowrap overflow-hidden text-ellipsis">{tab}</span>
    

    Furthermore, you'd want to apply min-width: 0 to override the min-width: min-content of each of the flex layout children, so that they can properly shrink narrower than the text content, allowing for the truncation effect to be visible:

    {tabs.map((tab, index) => (
      //  outer div so that when you hover over tab, it does not colour all the way to tab border
      <div
        key={index}
        className="… min-w-0"
      >
        <div
          className="… min-w-0"
          title={tab}
        >
          <span class="whitespace-nowrap overflow-hidden text-ellipsis">{tab}</span>
    

    const { useState } = React;
    
    const AddIcon = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor' class='size-6'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M12 4.5v15m7.5-7.5h-15' /%3E%3C/svg%3E%0A";
    
    const Tabs = () => {
      const [tabs, setTabs] = useState(Array(20).fill().map((_, i) => `Tab ${i + 1}`));
    
      const addNewTab = () => {
        setTabs([...tabs, `Tab ${tabs.length + 1}`]);
      };
    
      return (
        // outer div ensures that the tabs take up the remaining space in whatever view we use
        <div className="flex-1 overflow-hidden">
          <div className="flex overflow-hidden items-center h-8">
            {tabs.map((tab, index) => (
              //  outer div so that when you hover over tab, it does not colour all the way to tab border
              <div
                key={index}
                className="flex basis-40 justify-center items-center h-8 border-r px-1 border-gray-300 min-w-0"
              >
                <div
                  className="h-7 basis-36 flex items-center text-sm hover:bg-slate-300 rounded min-w-0"
                  title={tab}
                >
                  <span className="whitespace-nowrap overflow-hidden text-ellipsis">{tab}</span>
                </div>
              </div>
            ))}
            {/* add styling to button to ensure */}
            <button
              className="ml-2 hover:bg-slate-300 rounded flex items-center justify-center h-7 w-7 flex-shrink-0"
              onClick={addNewTab}
            >
              <img src={AddIcon} alt="Add icon" className="h-5 w-5" />
            </button>
          </div>
        </div>
      );
    };
    
    
    ReactDOM.createRoot(document.getElementById('app')).render(<Tabs/>);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js" integrity="sha512-QVs8Lo43F9lSuBykadDb0oSXDL/BbZ588urWVCRwSIoewQv/Ewg1f84mK3U790bZ0FfhFa1YSQUmIhG+pIRKeg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js" integrity="sha512-6a1107rTlA4gYpgHAqbwLAtxmWipBdJFcq8y5S/aTge3Bp+VAklABm2LO+Kg51vOWR9JMZq1Ovjl5tpluNpTeQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdn.tailwindcss.com/3.4.5"></script>
    
    <div id="app"></div>