diff --git a/frontend/src/metabase/browse/components/BrowseModels.unit.spec.tsx b/frontend/src/metabase/browse/components/BrowseModels.unit.spec.tsx
index 1d059fc2f9d1082022f891c58e95caf15b1e8fc7..e05f459ff2e5147c0f6b411fd317ef5667de8f08 100644
--- a/frontend/src/metabase/browse/components/BrowseModels.unit.spec.tsx
+++ b/frontend/src/metabase/browse/components/BrowseModels.unit.spec.tsx
@@ -4,7 +4,6 @@ import {
   setupSettingsEndpoints,
 } from "__support__/server-mocks";
 import { renderWithProviders, screen, within } from "__support__/ui";
-import { defaultRootCollection } from "metabase/admin/permissions/pages/CollectionPermissionsPage/tests/setup";
 import {
   createMockCollection,
   createMockSearchResult,
@@ -15,6 +14,11 @@ import { createMockModelResult, createMockRecentModel } from "../test-utils";
 
 import { BrowseModels } from "./BrowseModels";
 
+const defaultRootCollection = createMockCollection({
+  id: "root",
+  name: "Our analytics",
+});
+
 const setup = (modelCount: number, recentModelCount = 5) => {
   const mockModelResults = mockModels.map(model =>
     createMockModelResult(model),
@@ -249,14 +253,14 @@ const mockModels = [
   {
     id: 21,
     name: "Model 21",
-    collection: defaultRootCollection,
+    collection: defaultRootCollection, // Our analytics
     last_editor_common_name: "Bobby",
     last_edited_at: "2000-01-01T00:00:00.000Z",
   },
   {
     id: 22,
     name: "Model 22",
-    collection: defaultRootCollection,
+    collection: defaultRootCollection, // Our analytics
     last_editor_common_name: "Bobby",
     last_edited_at: "2000-01-01T00:00:00.000Z",
   },
@@ -284,7 +288,9 @@ describe("BrowseModels", () => {
     });
     expect(modelsTable).toBeInTheDocument();
     expect(
-      await screen.findAllByTestId("path-for-collection: Our analytics"),
+      await within(modelsTable).findAllByTestId(
+        "path-for-collection: Our analytics",
+      ),
     ).toHaveLength(2);
     expect(
       await within(modelsTable).findByText("Model 20"),
@@ -304,9 +310,7 @@ describe("BrowseModels", () => {
     });
     expect(await within(modelsTable).findByText("Model 1")).toBeInTheDocument();
     expect(
-      await within(modelsTable).findAllByTestId(
-        "breadcrumbs-for-collection: Alpha",
-      ),
+      await within(modelsTable).findAllByTestId("path-for-collection: Alpha"),
     ).toHaveLength(3);
   });
 
diff --git a/frontend/src/metabase/browse/components/CollectionBreadcrumbsWithTooltip.styled.tsx b/frontend/src/metabase/browse/components/CollectionBreadcrumbsWithTooltip.styled.tsx
deleted file mode 100644
index 22d5944a987a905da89b1d97af4bf4cf7217511f..0000000000000000000000000000000000000000
--- a/frontend/src/metabase/browse/components/CollectionBreadcrumbsWithTooltip.styled.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import styled from "@emotion/styled";
-
-import { ResponsiveChild } from "metabase/components/ResponsiveContainer/ResponsiveContainer";
-import Link from "metabase/core/components/Link";
-import { FixedSizeIcon, Flex, Group } from "metabase/ui";
-
-import { Ellipsis } from "./Ellipsis";
-
-/** When a cell is narrower than this width, breadcrumbs within it change significantly */
-const breadcrumbBreakpoint = "10rem";
-
-export const Breadcrumb = styled(ResponsiveChild)<{
-  maxWidth: string;
-  isSoleBreadcrumb: boolean;
-  index: number;
-}>`
-  ${({ maxWidth }) => {
-    return maxWidth ? `td & { max-width: ${maxWidth} };` : "";
-  }}
-  color: var(--mb-color-text-dark);
-  line-height: 1;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-  padding-top: 1px;
-  padding-bottom: 1px;
-  ${props => {
-    return `
-    @container ${props.containerName} (width < ${breadcrumbBreakpoint}) {
-      ${props.index === 0 && !props.isSoleBreadcrumb ? `display: none;` : ""}
-      td & { max-width: calc(95cqw - ${props.isSoleBreadcrumb ? 1 : 3}rem); };
-    }`;
-  }}
-`;
-
-export const CollectionLink = styled(Link)`
-  :hover {
-    &,
-    * {
-      color: var(--mb-color-brand);
-
-      .collection-path-separator {
-        color: var(--mb-color-brand-alpha-88);
-      }
-    }
-  }
-`;
-
-export const InitialEllipsis = styled(Ellipsis)``;
-InitialEllipsis.defaultProps = {
-  includeSep: false,
-};
-
-export const CollectionBreadcrumbsWrapper = styled(ResponsiveChild)`
-  line-height: 1;
-  ${InitialEllipsis} {
-    display: none;
-  }
-  ${props => {
-    return `
-    @container ${props.containerName} (width < ${breadcrumbBreakpoint}) {
-      ${EllipsisAndSeparator} {
-        display: none;
-      }
-      ${InitialEllipsis} {
-        display: inline;
-      }
-    }
-    `;
-  }}
-`;
-
-export const BreadcrumbGroup = styled(Group)`
-  flex-flow: row nowrap;
-`;
-
-export const CollectionsIcon = styled(FixedSizeIcon)`
-  margin-inline-end: 0.5rem;
-`;
-
-export const EllipsisAndSeparator = styled(Flex)``;
diff --git a/frontend/src/metabase/browse/components/CollectionBreadcrumbsWithTooltip.tsx b/frontend/src/metabase/browse/components/CollectionBreadcrumbsWithTooltip.tsx
deleted file mode 100644
index a96085dd695b25b0f11430b3762d498f3b5c5313..0000000000000000000000000000000000000000
--- a/frontend/src/metabase/browse/components/CollectionBreadcrumbsWithTooltip.tsx
+++ /dev/null
@@ -1,150 +0,0 @@
-import { useEffect, useRef, useState } from "react";
-
-import { getCollectionName } from "metabase/collections/utils";
-import { ResponsiveContainer } from "metabase/components/ResponsiveContainer/ResponsiveContainer";
-import { Ellipsified } from "metabase/core/components/Ellipsified";
-import { useAreAnyTruncated } from "metabase/hooks/use-is-truncated";
-import resizeObserver from "metabase/lib/resize-observer";
-import * as Urls from "metabase/lib/urls";
-import { Flex, Tooltip } from "metabase/ui";
-import type { CollectionEssentials } from "metabase-types/api";
-
-import {
-  Breadcrumb,
-  BreadcrumbGroup,
-  CollectionBreadcrumbsWrapper,
-  CollectionLink,
-  CollectionsIcon,
-  InitialEllipsis,
-} from "./CollectionBreadcrumbsWithTooltip.styled";
-import { Ellipsis } from "./Ellipsis";
-import { PathSeparator } from "./PathSeparator";
-import { getBreadcrumbMaxWidths, getCollectionPathString } from "./utils";
-
-export const CollectionBreadcrumbsWithTooltip = ({
-  collection,
-  containerName,
-}: {
-  collection: CollectionEssentials;
-  containerName: string;
-}) => {
-  const collections = (
-    (collection.effective_ancestors as CollectionEssentials[]) || []
-  ).concat(collection);
-  const pathString = getCollectionPathString(collection);
-  const ellipsifyPath = collections.length > 2;
-  const shownCollections = ellipsifyPath
-    ? [collections[0], collections[collections.length - 1]]
-    : collections;
-  const justOneShown = shownCollections.length === 1;
-
-  const { areAnyTruncated, ref } = useAreAnyTruncated<HTMLDivElement>();
-
-  const initialEllipsisRef = useRef<HTMLDivElement | null>(null);
-  const [
-    isFirstCollectionDisplayedAsEllipsis,
-    setIsFirstCollectionDisplayedAsEllipsis,
-  ] = useState(false);
-
-  useEffect(() => {
-    const initialEllipsis = initialEllipsisRef.current;
-    if (!initialEllipsis) {
-      return;
-    }
-    const handleResize = () => {
-      // The initial ellipsis might be hidden via CSS,
-      // so we need to check whether it is displayed via getComputedStyle
-      const style = window.getComputedStyle(initialEllipsis);
-      setIsFirstCollectionDisplayedAsEllipsis(style.display !== "none");
-    };
-    resizeObserver.subscribe(initialEllipsis, handleResize);
-    return () => {
-      resizeObserver.unsubscribe(initialEllipsis, handleResize);
-    };
-  }, [initialEllipsisRef]);
-
-  const isTooltipEnabled =
-    areAnyTruncated || ellipsifyPath || isFirstCollectionDisplayedAsEllipsis;
-
-  const maxWidths = getBreadcrumbMaxWidths(shownCollections, 96, ellipsifyPath);
-
-  return (
-    <Tooltip
-      label={pathString}
-      disabled={!isTooltipEnabled}
-      multiline
-      maw="20rem"
-    >
-      <ResponsiveContainer
-        aria-label={pathString}
-        data-testid={`breadcrumbs-for-collection: ${collection.name}`}
-        name={containerName}
-        w="auto"
-      >
-        <CollectionLink to={Urls.collection(collection)}>
-          <Flex
-            align="center"
-            w="100%"
-            lh="1"
-            style={{ flexFlow: "row nowrap" }}
-          >
-            <CollectionsIcon
-              name="folder"
-              // Stopping propagation so that the parent <tr>'s onclick won't fire
-              onClick={(e: React.MouseEvent) => e.stopPropagation()}
-            />
-            {shownCollections.map((collection, index) => {
-              const key = `collection${collection.id}`;
-              return (
-                <BreadcrumbGroup
-                  spacing={0}
-                  key={key}
-                  // Stopping propagation so that the parent <tr>'s onclick won't fire
-                  onClick={(e: React.MouseEvent) => e.stopPropagation()}
-                >
-                  {index > 0 && <PathSeparator />}
-                  <CollectionBreadcrumbsWrapper
-                    containerName={containerName}
-                    style={{ alignItems: "center" }}
-                    w="auto"
-                    display="flex"
-                  >
-                    {index === 0 && !justOneShown && (
-                      <InitialEllipsis ref={initialEllipsisRef} />
-                    )}
-                    {index > 0 && ellipsifyPath && <Ellipsis />}
-                    <Breadcrumb
-                      maxWidth={maxWidths[index]}
-                      index={index}
-                      isSoleBreadcrumb={collections.length === 1}
-                      containerName={containerName}
-                      ref={(el: HTMLDivElement | null) =>
-                        el && ref.current.set(key, el)
-                      }
-                      key={collection.id}
-                    >
-                      {getCollectionName(collection)}
-                    </Breadcrumb>
-                  </CollectionBreadcrumbsWrapper>
-                </BreadcrumbGroup>
-              );
-            })}
-          </Flex>
-        </CollectionLink>
-      </ResponsiveContainer>
-    </Tooltip>
-  );
-};
-
-export const SimpleCollectionDisplay = ({
-  collection,
-}: {
-  collection: CollectionEssentials;
-}) => {
-  return (
-    <Flex align="center">
-      <CollectionsIcon name="folder" />
-      <Ellipsified>{getCollectionName(collection)}</Ellipsified>
-    </Flex>
-  );
-};
diff --git a/frontend/src/metabase/browse/components/CollectionBreadcrumbsWithTooltip.unit.spec.tsx b/frontend/src/metabase/browse/components/CollectionBreadcrumbsWithTooltip.unit.spec.tsx
deleted file mode 100644
index e48aa72861c790d0f4f95ada45a85654a418bf83..0000000000000000000000000000000000000000
--- a/frontend/src/metabase/browse/components/CollectionBreadcrumbsWithTooltip.unit.spec.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import { renderWithProviders, screen } from "__support__/ui";
-import type { Collection } from "metabase-types/api";
-import { createMockCollection } from "metabase-types/api/mocks";
-
-import { CollectionBreadcrumbsWithTooltip } from "./CollectionBreadcrumbsWithTooltip";
-
-const setup = (collection: Collection) => {
-  return renderWithProviders(
-    <CollectionBreadcrumbsWithTooltip
-      collection={collection}
-      containerName="Container"
-    />,
-  );
-};
-const collectionAlpha = createMockCollection({ id: 99, name: "Alpha" });
-const collectionBeta = createMockCollection({
-  id: 1,
-  name: "Beta",
-  effective_ancestors: [collectionAlpha],
-});
-const collectionCharlie = createMockCollection({
-  id: 2,
-  name: "Charlie",
-  effective_ancestors: [collectionAlpha, collectionBeta],
-});
-
-describe("CollectionBreadcrumbsWithTooltip", () => {
-  it("should show a single collection", () => {
-    setup(collectionAlpha);
-    expect(screen.getByLabelText("Alpha")).toBeInTheDocument();
-    expect(screen.getByText("Alpha")).toBeInTheDocument();
-  });
-
-  it("should display a path of length two without abbreviations", () => {
-    setup(collectionBeta);
-    const breadcrumbs = screen.getByLabelText("Alpha / Beta");
-    expect(breadcrumbs).toBeInTheDocument();
-    expect(breadcrumbs?.textContent).toMatch(/Alpha\/Beta/);
-  });
-
-  it("should display a path of length three as the first and last collection with an ellipsis in between", () => {
-    setup(collectionCharlie);
-    const breadcrumbs = screen.getByLabelText("Alpha / Beta / Charlie");
-    expect(breadcrumbs).toBeInTheDocument();
-    expect(breadcrumbs?.textContent).toMatch(/Alpha\/…\/Charlie/);
-  });
-});
diff --git a/frontend/src/metabase/browse/components/Ellipsis.tsx b/frontend/src/metabase/browse/components/Ellipsis.tsx
deleted file mode 100644
index e748d098625a8f2aad4ee218b6f5e596b79c4d32..0000000000000000000000000000000000000000
--- a/frontend/src/metabase/browse/components/Ellipsis.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import type { FC } from "react";
-import { forwardRef } from "react";
-
-import type { FlexProps } from "metabase/ui";
-import { Text } from "metabase/ui";
-
-import type { RefProp } from "../types";
-
-import { EllipsisAndSeparator } from "./CollectionBreadcrumbsWithTooltip.styled";
-import { PathSeparator } from "./PathSeparator";
-type EllipsisProps = {
-  includeSep?: boolean;
-} & FlexProps;
-
-export const Ellipsis: FC<
-  EllipsisProps & Partial<RefProp<HTMLDivElement | null>>
-> = forwardRef<HTMLDivElement, EllipsisProps>(
-  ({ includeSep = true, ...flexProps }, ref) => (
-    <EllipsisAndSeparator
-      ref={ref}
-      align="center"
-      className="ellipsis-and-separator"
-      {...flexProps}
-    >
-      <Text lh={1}>…</Text>
-      {includeSep && <PathSeparator />}
-    </EllipsisAndSeparator>
-  ),
-);
-Ellipsis.displayName = "Ellipsis";
diff --git a/frontend/src/metabase/browse/components/ModelsTable.module.css b/frontend/src/metabase/browse/components/ModelsTable.module.css
new file mode 100644
index 0000000000000000000000000000000000000000..f29119d547afe2c2cd394305494d1847877b0312
--- /dev/null
+++ b/frontend/src/metabase/browse/components/ModelsTable.module.css
@@ -0,0 +1,5 @@
+.collectionLink {
+  :hover {
+    color: var(--mb-color-brand) !important;
+  }
+}
diff --git a/frontend/src/metabase/browse/components/ModelsTable.tsx b/frontend/src/metabase/browse/components/ModelsTable.tsx
index b1a211dd8f34b5fb9ac233649c85945854b59bc5..0f508b326c65416dd5607182942142aa666a22ab 100644
--- a/frontend/src/metabase/browse/components/ModelsTable.tsx
+++ b/frontend/src/metabase/browse/components/ModelsTable.tsx
@@ -1,13 +1,9 @@
-import {
-  type PropsWithChildren,
-  useEffect,
-  useState,
-  type CSSProperties,
-} from "react";
+import { type PropsWithChildren, useState, type CSSProperties } from "react";
 import { push } from "react-router-redux";
 import { t } from "ttag";
 
 import { getCollectionName } from "metabase/collections/utils";
+import { EllipsifiedPath } from "metabase/common/components/EllipsifiedPath";
 import { useLocale } from "metabase/common/hooks/use-locale/use-locale";
 import EntityItem from "metabase/components/EntityItem";
 import { SortableColumnHeader } from "metabase/components/ItemsTable/BaseItemsTable";
@@ -21,7 +17,7 @@ import {
 import { Columns } from "metabase/components/ItemsTable/Columns";
 import type { ResponsiveProps } from "metabase/components/ItemsTable/utils";
 import { Ellipsified } from "metabase/core/components/Ellipsified";
-import { color } from "metabase/lib/colors";
+import Link from "metabase/core/components/Link";
 import { useDispatch } from "metabase/lib/redux";
 import * as Urls from "metabase/lib/urls";
 import {
@@ -30,6 +26,8 @@ import {
   type IconProps,
   type IconName,
   Skeleton,
+  FixedSizeIcon,
+  Box,
 } from "metabase/ui";
 import { Repeat } from "metabase/ui/components/feedback/Skeleton/Repeat";
 import { SortDirection, type SortingOptions } from "metabase-types/api/sorting";
@@ -38,18 +36,18 @@ import { trackModelClick } from "../analytics";
 import type { ModelResult } from "../types";
 import { getIcon } from "../utils";
 
-import {
-  CollectionBreadcrumbsWithTooltip,
-  SimpleCollectionDisplay,
-} from "./CollectionBreadcrumbsWithTooltip";
-import { CollectionsIcon } from "./CollectionBreadcrumbsWithTooltip.styled";
 import { EllipsifiedWithMarkdownTooltip } from "./EllipsifiedWithMarkdownTooltip";
+import S from "./ModelsTable.module.css";
 import {
   ModelCell,
   ModelNameColumn,
   ModelTableRow,
 } from "./ModelsTable.styled";
-import { getModelDescription, sortModels } from "./utils";
+import {
+  getCollectionPathString,
+  getModelDescription,
+  sortModels,
+} from "./utils";
 
 export interface ModelsTableProps {
   models?: ModelResult[];
@@ -74,18 +72,10 @@ const DEFAULT_SORTING_OPTIONS: SortingOptions = {
   sort_direction: SortDirection.Asc,
 };
 
-const LARGE_DATASET_THRESHOLD = 500;
-
 export const ModelsTable = ({
   models = [],
   skeleton = false,
 }: ModelsTableProps) => {
-  // for large datasets, we need to simplify the display to avoid performance issues
-  const isLargeDataset = models.length > LARGE_DATASET_THRESHOLD;
-
-  const [showLoadingManyRows, setShowLoadingManyRows] =
-    useState(isLargeDataset);
-
   const [sortingOptions, setSortingOptions] = useState<SortingOptions>(
     DEFAULT_SORTING_OPTIONS,
   );
@@ -100,20 +90,9 @@ export const ModelsTable = ({
   const handleUpdateSortOptions = skeleton
     ? undefined
     : (newSortingOptions: SortingOptions) => {
-        if (isLargeDataset) {
-          setShowLoadingManyRows(true);
-        }
         setSortingOptions(newSortingOptions);
       };
 
-  useEffect(() => {
-    // we need a better virtualized table solution for large datasets
-    // for now, we show loading text to make this component feel more responsive
-    if (isLargeDataset && showLoadingManyRows) {
-      setTimeout(() => setShowLoadingManyRows(false), 10);
-    }
-  }, [isLargeDataset, showLoadingManyRows, sortedModels]);
-
   return (
     <Table aria-label={skeleton ? undefined : t`Table of models`}>
       <colgroup>
@@ -169,19 +148,13 @@ export const ModelsTable = ({
         </tr>
       </thead>
       <TBody>
-        {showLoadingManyRows ? (
-          <TableLoader />
-        ) : skeleton ? (
+        {skeleton ? (
           <Repeat times={7}>
             <TBodyRowSkeleton />
           </Repeat>
         ) : (
           sortedModels.map((model: ModelResult) => (
-            <TBodyRow
-              model={model}
-              key={`${model.model}-${model.id}`}
-              simpleDisplay={isLargeDataset}
-            />
+            <TBodyRow model={model} key={`${model.model}-${model.id}`} />
           ))
         )}
       </TBody>
@@ -191,15 +164,12 @@ export const ModelsTable = ({
 
 const TBodyRow = ({
   model,
-  simpleDisplay,
   skeleton,
 }: {
   model: ModelResult;
-  simpleDisplay: boolean;
   skeleton?: boolean;
 }) => {
   const icon = getIcon(model);
-  const containerName = `collections-path-for-${model.id}`;
   const dispatch = useDispatch();
   const { id, name } = model;
 
@@ -242,14 +212,24 @@ const TBodyRow = ({
         }`}
         {...collectionProps}
       >
-        {simpleDisplay ? (
-          <SimpleCollectionDisplay collection={model.collection} />
-        ) : (
-          <CollectionBreadcrumbsWithTooltip
-            containerName={containerName}
-            collection={model.collection}
-          />
-        )}
+        <Link
+          className={S.collectionLink}
+          to={Urls.collection(model.collection)}
+          onClick={e => e.stopPropagation()}
+        >
+          <Flex gap="sm">
+            <FixedSizeIcon name="folder" />
+            <Box w="calc(100% - 1.5rem)">
+              <EllipsifiedPath
+                tooltip={getCollectionPathString(model.collection)}
+                items={[
+                  ...(model.collection?.effective_ancestors || []),
+                  model.collection,
+                ].map(c => getCollectionName(c))}
+              />
+            </Box>
+          </Flex>
+        </Link>
       </ModelCell>
 
       {/* Description */}
@@ -295,7 +275,7 @@ const NameCell = ({
         <Icon
           size={16}
           {...icon}
-          color={color("brand")}
+          color={"var(--mb-color-brand)"}
           style={{ flexShrink: 0 }}
         />
         {children || (
@@ -310,16 +290,6 @@ const NameCell = ({
   );
 };
 
-const TableLoader = () => (
-  <tr>
-    <td colSpan={4}>
-      <Flex justify="center" color="text-light">
-        {t`Loading…`}
-      </Flex>
-    </td>
-  </tr>
-);
-
 const CellTextSkeleton = () => {
   return <Skeleton natural h="16.8px" />;
 };
@@ -335,8 +305,8 @@ const TBodyRowSkeleton = ({ style }: { style?: CSSProperties }) => {
 
       {/* Collection */}
       <ModelCell {...collectionProps}>
-        <Flex>
-          <CollectionsIcon name="folder" />
+        <Flex gap=".5rem">
+          <FixedSizeIcon name="folder" />
           <CellTextSkeleton />
         </Flex>
       </ModelCell>
diff --git a/frontend/src/metabase/browse/components/PathSeparator.tsx b/frontend/src/metabase/browse/components/PathSeparator.tsx
deleted file mode 100644
index dba1db2e93a08baf35cd664c0e357902ec03ccc8..0000000000000000000000000000000000000000
--- a/frontend/src/metabase/browse/components/PathSeparator.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { Text } from "metabase/ui";
-
-import { pathSeparatorChar } from "./constants";
-
-export const PathSeparator = () => (
-  <Text
-    className="collection-path-separator"
-    color="text-light"
-    mx=".2rem"
-    py={1}
-  >
-    {pathSeparatorChar}
-  </Text>
-);
diff --git a/frontend/src/metabase/common/components/EllipsifiedPath/EllipsifiedPath.module.css b/frontend/src/metabase/common/components/EllipsifiedPath/EllipsifiedPath.module.css
new file mode 100644
index 0000000000000000000000000000000000000000..98d405b1e7068d680691eb7ce81e1f913488a349
--- /dev/null
+++ b/frontend/src/metabase/common/components/EllipsifiedPath/EllipsifiedPath.module.css
@@ -0,0 +1,51 @@
+.path {
+  flex-grow: 1;
+  display: flex;
+  flex-flow: row nowrap;
+  overflow-x: hidden;
+  container-type: inline-size;
+}
+
+.slash {
+  opacity: 0.5;
+  min-width: 0;
+  flex-shrink: 0;
+  padding-inline: 0.1rem;
+}
+
+.item,
+.slash {
+  @container (max-width: 6rem) {
+    &:not(&:last-child) {
+      display: none;
+    }
+  }
+}
+
+.dots {
+  opacity: 0.5;
+  display: none;
+
+  @container (max-width: 6rem) {
+    display: flex;
+  }
+}
+
+.item {
+  flex-grow: 1;
+  min-width: 0;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  max-width: fit-content;
+
+  /* The first path item should try to be a bit bigger than average */
+  &:nth-child(2) {
+    flex-basis: 100%;
+  }
+
+  /* The last path item should show all of itself if possible */
+  &:last-child {
+    flex-basis: 1000%;
+  }
+}
diff --git a/frontend/src/metabase/common/components/EllipsifiedPath/EllipsifiedPath.tsx b/frontend/src/metabase/common/components/EllipsifiedPath/EllipsifiedPath.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..2c59b7236b256802bdd6115d65016a4cf0fc486f
--- /dev/null
+++ b/frontend/src/metabase/common/components/EllipsifiedPath/EllipsifiedPath.tsx
@@ -0,0 +1,47 @@
+import React from "react";
+
+import { useAreAnyTruncated } from "metabase/hooks/use-is-truncated";
+import { Tooltip } from "metabase/ui";
+
+import S from "./EllipsifiedPath.module.css";
+
+type EllipsifiedPathProps = { items: string[]; tooltip: string };
+
+/**
+ * Displays a path such as "Collection / Subcollection / Subsubcollection /
+ * Parent Collection".
+ *
+ * If the path is too long to fit, some items may be truncated, like this:
+ * "Collection / Subcollec... / Subsub... / Parent Collection".
+ *
+ * A tooltip is shown if any items are truncated.
+ */
+export const EllipsifiedPath = ({ items, tooltip }: EllipsifiedPathProps) => {
+  const { areAnyTruncated, ref } = useAreAnyTruncated<HTMLDivElement>();
+
+  return (
+    <Tooltip label={tooltip} disabled={!areAnyTruncated} multiline maw="20rem">
+      <div className={S.path}>
+        {items.length > 1 && (
+          <div className={S.dots}>
+            … <div className={S.slash}>/</div>
+          </div>
+        )}
+        {items.map((item, index) => {
+          const key = `${item}${index}`;
+          return (
+            <React.Fragment key={key}>
+              <div
+                ref={el => el && ref.current.set(key, el)}
+                className={S.item}
+              >
+                {item}
+              </div>
+              {index < items.length - 1 && <div className={S.slash}>/</div>}
+            </React.Fragment>
+          );
+        })}
+      </div>
+    </Tooltip>
+  );
+};
diff --git a/frontend/src/metabase/common/components/EllipsifiedPath/index.ts b/frontend/src/metabase/common/components/EllipsifiedPath/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..29d445092bafff7756adc32d57a8e5aab45cdaa3
--- /dev/null
+++ b/frontend/src/metabase/common/components/EllipsifiedPath/index.ts
@@ -0,0 +1 @@
+export { EllipsifiedPath } from "./EllipsifiedPath";