diff --git a/frontend/src/metabase/css/core/scroll.css b/frontend/src/metabase/css/core/scroll.css
index 12fccedf309f12c5fae4b8165ebb6f78ca64419d..97100825e9dbf59af557e271900d059a7f94521e 100644
--- a/frontend/src/metabase/css/core/scroll.css
+++ b/frontend/src/metabase/css/core/scroll.css
@@ -67,10 +67,12 @@
     display: none; /* Safari and Chrome */
 }
 
-.scroll-hide-all, .scroll-hide-all * {
+.scroll-hide-all,
+.scroll-hide-all * {
     -ms-overflow-style: none;  /* IE 10+ */
     overflow: -moz-scrollbars-none;  /* Firefox */
 }
+.scroll-hide-all::-webkit-scrollbar,
 .scroll-hide-all *::-webkit-scrollbar {
     display: none; /* Safari and Chrome */
 }
diff --git a/frontend/src/metabase/visualizations/components/TableInteractive.css b/frontend/src/metabase/visualizations/components/TableInteractive.css
index fd07f661939a3007812ce5b59f3484223ede6b6a..42faf55c441d46e64c8f14bf33ccd062d370078f 100644
--- a/frontend/src/metabase/visualizations/components/TableInteractive.css
+++ b/frontend/src/metabase/visualizations/components/TableInteractive.css
@@ -6,13 +6,11 @@
   font-weight: 700;
 }
 
-.TableInteractive-headerCellData:hover {
-    cursor: pointer;
+.TableInteractive-headerCellData .Icon {
+  opacity: 0;
 }
 
-.TableInteractive-headerCellData .Icon       { opacity: 0; }
-.TableInteractive-headerCellData:hover .Icon,
-.TableInteractive-headerCellData--sorted .Icon     {
+.TableInteractive-headerCellData--sorted .Icon {
     opacity: 1;
     transition: opacity .3s linear;
 }
diff --git a/frontend/src/metabase/visualizations/components/TableInteractive.jsx b/frontend/src/metabase/visualizations/components/TableInteractive.jsx
index 32e26d8220e2f1f81555286712350f57ff0cf300..c16ab22c635083c10a7a7db982a678d11a27cc83 100644
--- a/frontend/src/metabase/visualizations/components/TableInteractive.jsx
+++ b/frontend/src/metabase/visualizations/components/TableInteractive.jsx
@@ -8,11 +8,9 @@ import "./TableInteractive.css";
 
 import Icon from "metabase/components/Icon.jsx";
 
-import Value from "metabase/components/Value.jsx";
-
-import { capitalize } from "metabase/lib/formatting";
+import { formatValue, capitalize } from "metabase/lib/formatting";
 import { getFriendlyName } from "metabase/visualizations/lib/utils";
-import { getTableCellClickedObject } from "metabase/visualizations/lib/table";
+import { getTableCellClickedObject, isColumnRightAligned } from "metabase/visualizations/lib/table";
 
 import _ from "underscore";
 import cx from "classnames";
@@ -21,8 +19,8 @@ import ExplicitSize from "metabase/components/ExplicitSize.jsx";
 import { Grid, ScrollSync } from "react-virtualized";
 import Draggable from "react-draggable";
 
-const HEADER_HEIGHT = 50;
-const ROW_HEIGHT = 35;
+const HEADER_HEIGHT = 36;
+const ROW_HEIGHT = 30;
 const MIN_COLUMN_WIDTH = ROW_HEIGHT;
 const RESIZE_HANDLE_WIDTH = 5;
 
@@ -226,21 +224,23 @@ export default class TableInteractive extends Component<*, Props, State> {
         return (
             <div
                 key={key} style={style}
-                className={cx("TableInteractive-cellWrapper cellData", {
+                className={cx("TableInteractive-cellWrapper", {
                     "TableInteractive-cellWrapper--firstColumn": columnIndex === 0,
-                    "cursor-pointer": isClickable
+                    "cursor-pointer": isClickable,
+                    "justify-end": isColumnRightAligned(column)
                 })}
                 onClick={isClickable && ((e) => {
                     onVisualizationClick({ ...clicked, element: e.currentTarget });
                 })}
             >
-                <Value
-                    className="link"
-                    type="cell"
-                    value={value}
-                    column={column}
-                    onResize={this.onCellResize.bind(this, columnIndex)}
-                />
+                <div className="cellData">
+                    {/* using formatValue instead of <Value> here for performance. The later wraps in an extra <span> */}
+                    {formatValue(value, {
+                        column: column,
+                        type: "cell",
+                        jsx: true
+                    })}
+                </div>
             </div>
         );
     }
@@ -271,6 +271,10 @@ export default class TableInteractive extends Component<*, Props, State> {
 
         const isClickable = onVisualizationClick && visualizationIsClickable(clicked);
         const isSortable = isClickable && column.source;
+        const isRightAligned = isColumnRightAligned(column);
+
+        const isSorted = sort && sort[0] && sort[0][0] === column.id;
+        const isAscending = sort && sort[0] && sort[0][1] === "ascending";
 
         return (
             <div
@@ -278,22 +282,21 @@ export default class TableInteractive extends Component<*, Props, State> {
                 style={{ ...style, overflow: "visible" /* ensure resize handle is visible */ }}
                 className={cx("TableInteractive-cellWrapper TableInteractive-headerCellData", {
                     "TableInteractive-cellWrapper--firstColumn": columnIndex === 0,
-                    "TableInteractive-headerCellData--sorted": (sort && sort[0] && sort[0][0] === column.id),
+                    "TableInteractive-headerCellData--sorted": isSorted,
+                    "cursor-pointer": isClickable,
+                    "justify-end": isRightAligned
+                })}
+                onClick={isClickable && ((e) => {
+                    onVisualizationClick({ ...clicked, element: e.currentTarget });
                 })}
             >
-                <div
-                    className={cx("cellData", { "cursor-pointer": isClickable })}
-                    onClick={isClickable && ((e) => {
-                        onVisualizationClick({ ...clicked, element: e.currentTarget });
-                    })}
-                >
+                <div className="cellData">
+                    {isSortable && isRightAligned &&
+                        <Icon className="Icon mr1" name={isAscending ? "chevronup" : "chevrondown"} size={8} />
+                    }
                     {columnTitle}
-                    {isSortable &&
-                        <Icon
-                            className="Icon ml1"
-                            name={sort && sort[0] && sort[0][1] === "ascending" ? "chevronup" : "chevrondown"}
-                            size={8}
-                        />
+                    {isSortable && !isRightAligned &&
+                        <Icon className="Icon ml1" name={isAscending ? "chevronup" : "chevrondown"} size={8} />
                     }
                 </div>
                 <Draggable
diff --git a/frontend/src/metabase/visualizations/components/TableSimple.jsx b/frontend/src/metabase/visualizations/components/TableSimple.jsx
index c79e17910203353dc917ec5be1f54ee02fce93b3..08eaf523bf9b7af294807b3becf44b5a15a0170c 100644
--- a/frontend/src/metabase/visualizations/components/TableSimple.jsx
+++ b/frontend/src/metabase/visualizations/components/TableSimple.jsx
@@ -11,7 +11,7 @@ import Icon from "metabase/components/Icon.jsx";
 
 import { formatValue } from "metabase/lib/formatting";
 import { getFriendlyName } from "metabase/visualizations/lib/utils";
-import { getTableCellClickedObject } from "metabase/visualizations/lib/table";
+import { getTableCellClickedObject, isColumnRightAligned } from "metabase/visualizations/lib/table";
 
 import cx from "classnames";
 import _ from "underscore";
@@ -97,7 +97,14 @@ export default class TableSimple extends Component<*, Props, State> {
                             <thead ref="header">
                                 <tr>
                                     {cols.map((col, colIndex) =>
-                                        <th key={colIndex} className={cx("TableInteractive-headerCellData cellData text-brand-hover", { "TableInteractive-headerCellData--sorted": sortColumn === colIndex })} onClick={() => this.setSort(colIndex)}>
+                                        <th
+                                            key={colIndex}
+                                            className={cx("TableInteractive-headerCellData cellData text-brand-hover", {
+                                                "TableInteractive-headerCellData--sorted": sortColumn === colIndex,
+                                                "text-right": isColumnRightAligned(col)
+                                            })}
+                                            onClick={() => this.setSort(colIndex)}
+                                        >
                                             <div className="relative">
                                                 <Icon
                                                     name={sortDescending ? "chevrondown" : "chevronup"}
@@ -120,14 +127,16 @@ export default class TableSimple extends Component<*, Props, State> {
                                             <td
                                                 key={columnIndex}
                                                 style={{ whiteSpace: "nowrap" }}
-                                                className={cx("px1 border-bottom", {
-                                                    "cursor-pointer text-brand-hover": isClickable
-                                                })}
-                                                onClick={isClickable && ((e) => {
-                                                    onVisualizationClick({ ...clicked, element: e.currentTarget });
-                                                })}
+                                                className={cx("px1 border-bottom", { "text-right": isColumnRightAligned(cols[columnIndex]) })}
                                             >
-                                                { cell == null ? "-" : formatValue(cell, { column: cols[columnIndex], jsx: true }) }
+                                                <span
+                                                    className={cx({ "cursor-pointer text-brand-hover": isClickable })}
+                                                    onClick={isClickable && ((e) => {
+                                                        onVisualizationClick({ ...clicked, element: e.currentTarget });
+                                                    })}
+                                                >
+                                                    { cell == null ? "-" : formatValue(cell, { column: cols[columnIndex], jsx: true }) }
+                                                </span>
                                             </td>
                                         );
                                     })}
diff --git a/frontend/src/metabase/visualizations/lib/table.js b/frontend/src/metabase/visualizations/lib/table.js
index 3e05c3cb8278037c17d38b37e09456021b142138..8203808bc944ae10cd35f03ef6df5a49e6df4930 100644
--- a/frontend/src/metabase/visualizations/lib/table.js
+++ b/frontend/src/metabase/visualizations/lib/table.js
@@ -1,7 +1,8 @@
 /* @flow */
 
-import type { DatasetData } from "metabase/meta/types/Dataset";
+import type { DatasetData, Column } from "metabase/meta/types/Dataset";
 import type { ClickObject } from "metabase/meta/types/Visualization";
+import { isNumber, isCoordinate } from "metabase/lib/schema_metadata";
 
 export function getTableCellClickedObject(data: DatasetData, rowIndex: number, columnIndex: number, isPivoted: boolean): ClickObject {
     const { rows, cols } = data;
@@ -35,3 +36,11 @@ export function getTableCellClickedObject(data: DatasetData, rowIndex: number, c
         return { value, column };
     }
 }
+
+/*
+ * Returns whether the column should be right-aligned in a table.
+ * Includes numbers and lat/lon coordinates, but not zip codes, IDs, etc.
+ */
+export function isColumnRightAligned(column: Column) {
+    return isNumber(column) || isCoordinate(column);
+}
diff --git a/frontend/src/metabase/visualizations/lib/table.spec.js b/frontend/src/metabase/visualizations/lib/table.spec.js
index 9e89fa2f791c8f8758e4ca9074d1e67f264f3a6c..8b12d8c8480601951420d4273a8e93e889173607 100644
--- a/frontend/src/metabase/visualizations/lib/table.spec.js
+++ b/frontend/src/metabase/visualizations/lib/table.spec.js
@@ -1,4 +1,5 @@
-import { getTableCellClickedObject } from "./table";
+import { getTableCellClickedObject, isColumnRightAligned } from "./table";
+import { TYPE } from "metabase/lib/types";
 
 const RAW_COLUMN = {
     source: "fields"
@@ -40,4 +41,24 @@ describe("metabase/visualization/lib/table", () => {
             // TODO:
         })
     })
+
+    describe("isColumnRightAligned", () => {
+        it("should return true for numeric columns without a special type", () => {
+            expect(isColumnRightAligned({ base_type: TYPE.Integer })).toBe(true);
+        });
+        it("should return true for numeric columns with special type Number", () => {
+            expect(isColumnRightAligned({ base_type: TYPE.Integer, special_type: TYPE.Number })).toBe(true);
+        });
+        it("should return true for numeric columns with special type latitude or longitude ", () => {
+            expect(isColumnRightAligned({ base_type: TYPE.Integer, special_type: TYPE.Latitude })).toBe(true);
+            expect(isColumnRightAligned({ base_type: TYPE.Integer, special_type: TYPE.Longitude })).toBe(true);
+        });
+        it("should return false for numeric columns with special type zip code", () => {
+            expect(isColumnRightAligned({ base_type: TYPE.Integer, special_type: TYPE.ZipCode })).toBe(false)
+        });
+        it("should return false for numeric columns with special type FK or PK", () => {
+            expect(isColumnRightAligned({ base_type: TYPE.Integer, special_type: TYPE.FK })).toBe(false);
+            expect(isColumnRightAligned({ base_type: TYPE.Integer, special_type: TYPE.FK })).toBe(false);
+        });
+    })
 })