diff --git a/backend/src/baserow/contrib/builder/apps.py b/backend/src/baserow/contrib/builder/apps.py
index 8d0c880d2..6699cccb7 100644
--- a/backend/src/baserow/contrib/builder/apps.py
+++ b/backend/src/baserow/contrib/builder/apps.py
@@ -246,6 +246,7 @@ class BuilderConfig(AppConfig):
             InputThemeConfigBlockType,
             LinkThemeConfigBlockType,
             PageThemeConfigBlockType,
+            TableThemeConfigBlockType,
             TypographyThemeConfigBlockType,
         )
 
@@ -256,6 +257,7 @@ class BuilderConfig(AppConfig):
         theme_config_block_registry.register(ImageThemeConfigBlockType())
         theme_config_block_registry.register(PageThemeConfigBlockType())
         theme_config_block_registry.register(InputThemeConfigBlockType())
+        theme_config_block_registry.register(TableThemeConfigBlockType())
 
         from .workflow_actions.registries import builder_workflow_action_type_registry
         from .workflow_actions.workflow_action_types import (
diff --git a/backend/src/baserow/contrib/builder/elements/element_types.py b/backend/src/baserow/contrib/builder/elements/element_types.py
index 7fc52cc4b..ec8e4c0bb 100644
--- a/backend/src/baserow/contrib/builder/elements/element_types.py
+++ b/backend/src/baserow/contrib/builder/elements/element_types.py
@@ -46,6 +46,9 @@ from baserow.contrib.builder.elements.registries import (
 )
 from baserow.contrib.builder.pages.handler import PageHandler
 from baserow.contrib.builder.pages.models import Page
+from baserow.contrib.builder.theme.theme_config_block_types import (
+    TableThemeConfigBlockType,
+)
 from baserow.contrib.builder.types import ElementDict
 from baserow.core.formula import resolve_formula
 from baserow.core.formula.registries import formula_runtime_function_registry
@@ -237,8 +240,11 @@ class TableElementType(CollectionElementWithFieldsTypeMixin, ElementType):
             ),
             "styles": DynamicConfigBlockSerializer(
                 required=False,
-                property_name="button",
-                theme_config_block_type_name=ButtonThemeConfigBlockType.type,
+                property_name=["button", "table"],
+                theme_config_block_type_name=[
+                    ButtonThemeConfigBlockType.type,
+                    TableThemeConfigBlockType.type,
+                ],
                 serializer_kwargs={"required": False},
             ),
         }
diff --git a/backend/src/baserow/contrib/builder/migrations/0032_tablethemeconfigblock.py b/backend/src/baserow/contrib/builder/migrations/0032_tablethemeconfigblock.py
new file mode 100644
index 000000000..fb4657b55
--- /dev/null
+++ b/backend/src/baserow/contrib/builder/migrations/0032_tablethemeconfigblock.py
@@ -0,0 +1,175 @@
+# Generated by Django 4.2.13 on 2024-07-25 15:37
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+import baserow.core.fields
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("builder", "0031_remove_buttonelement_alignment_and_more"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="TableThemeConfigBlock",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "table_border_color",
+                    models.CharField(
+                        blank=True,
+                        default="#000000FF",
+                        help_text="The color of the table border",
+                        max_length=20,
+                    ),
+                ),
+                (
+                    "table_border_size",
+                    models.SmallIntegerField(default=1, help_text="Table border size"),
+                ),
+                (
+                    "table_border_radius",
+                    models.SmallIntegerField(
+                        default=0, help_text="Table border radius"
+                    ),
+                ),
+                (
+                    "table_header_background_color",
+                    models.CharField(
+                        blank=True,
+                        default="#edededff",
+                        help_text="The background color of the table header cells",
+                        max_length=20,
+                    ),
+                ),
+                (
+                    "table_header_text_color",
+                    models.CharField(
+                        blank=True,
+                        default="#000000ff",
+                        help_text="The text color of the table header cells",
+                        max_length=20,
+                    ),
+                ),
+                (
+                    "table_header_font_size",
+                    models.SmallIntegerField(
+                        default=13, help_text="The font size of the header cells"
+                    ),
+                ),
+                (
+                    "table_header_font_family",
+                    models.CharField(
+                        default="inter",
+                        help_text="The font family of the table header cells",
+                        max_length=250,
+                    ),
+                ),
+                (
+                    "table_header_text_alignment",
+                    models.CharField(
+                        choices=[
+                            ("left", "Left"),
+                            ("center", "Center"),
+                            ("right", "Right"),
+                        ],
+                        default="left",
+                        max_length=10,
+                    ),
+                ),
+                (
+                    "table_cell_background_color",
+                    models.CharField(
+                        blank=True,
+                        default="transparent",
+                        help_text="The background color of the table cells",
+                        max_length=20,
+                    ),
+                ),
+                (
+                    "table_cell_alternate_background_color",
+                    models.CharField(
+                        blank=True,
+                        default="transparent",
+                        help_text="The alternate background color of the table cells",
+                        max_length=20,
+                    ),
+                ),
+                (
+                    "table_cell_alignment",
+                    models.CharField(
+                        choices=[
+                            ("left", "Left"),
+                            ("center", "Center"),
+                            ("right", "Right"),
+                        ],
+                        default="left",
+                        max_length=10,
+                    ),
+                ),
+                (
+                    "table_cell_vertical_padding",
+                    models.SmallIntegerField(
+                        default=10, help_text="Table cell vertical padding"
+                    ),
+                ),
+                (
+                    "table_cell_horizontal_padding",
+                    models.SmallIntegerField(
+                        default=20, help_text="Table cell horizontal padding"
+                    ),
+                ),
+                (
+                    "table_vertical_separator_color",
+                    models.CharField(
+                        blank=True,
+                        default="#000000FF",
+                        help_text="The color of the table vertical separator",
+                        max_length=20,
+                    ),
+                ),
+                (
+                    "table_vertical_separator_size",
+                    models.SmallIntegerField(
+                        default=0, help_text="Table vertical separator size"
+                    ),
+                ),
+                (
+                    "table_horizontal_separator_color",
+                    models.CharField(
+                        blank=True,
+                        default="#000000FF",
+                        help_text="The color of the table horizontal separator",
+                        max_length=20,
+                    ),
+                ),
+                (
+                    "table_horizontal_separator_size",
+                    models.SmallIntegerField(
+                        default=1, help_text="Table horizontal separator size"
+                    ),
+                ),
+                (
+                    "builder",
+                    baserow.core.fields.AutoOneToOneField(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="%(class)s",
+                        to="builder.builder",
+                    ),
+                ),
+            ],
+            options={
+                "abstract": False,
+            },
+        ),
+    ]
diff --git a/backend/src/baserow/contrib/builder/theme/models.py b/backend/src/baserow/contrib/builder/theme/models.py
index 80161157b..3ba6cf0ea 100644
--- a/backend/src/baserow/contrib/builder/theme/models.py
+++ b/backend/src/baserow/contrib/builder/theme/models.py
@@ -329,3 +329,98 @@ class InputThemeConfigBlock(ThemeConfigBlock):
     input_horizontal_padding = models.SmallIntegerField(
         default=12, help_text="Input horizontal padding"
     )
+
+
+class TableThemeConfigBlock(ThemeConfigBlock):
+    """
+    Theme for tables.
+    """
+
+    # Table styles
+    table_border_color = models.CharField(
+        max_length=20,
+        default="#000000FF",
+        blank=True,
+        help_text="The color of the table border",
+    )
+    table_border_size = models.SmallIntegerField(
+        default=1, help_text="Table border size"
+    )
+    table_border_radius = models.SmallIntegerField(
+        default=0, help_text="Table border radius"
+    )
+
+    # Header styles
+    table_header_background_color = models.CharField(
+        max_length=20,
+        default="#edededff",
+        blank=True,
+        help_text="The background color of the table header cells",
+    )
+    table_header_text_color = models.CharField(
+        max_length=20,
+        default="#000000ff",
+        blank=True,
+        help_text="The text color of the table header cells",
+    )
+    table_header_font_size = models.SmallIntegerField(
+        default=13,
+        help_text="The font size of the header cells",
+    )
+    table_header_font_family = models.CharField(
+        max_length=250,
+        default="inter",
+        help_text="The font family of the table header cells",
+    )
+    table_header_text_alignment = models.CharField(
+        choices=HorizontalAlignments.choices,
+        max_length=10,
+        default=HorizontalAlignments.LEFT,
+    )
+
+    # Cell styles
+    table_cell_background_color = models.CharField(
+        max_length=20,
+        default="transparent",
+        blank=True,
+        help_text="The background color of the table cells",
+    )
+
+    table_cell_alternate_background_color = models.CharField(
+        max_length=20,
+        default="transparent",
+        blank=True,
+        help_text="The alternate background color of the table cells",
+    )
+    table_cell_alignment = models.CharField(
+        choices=HorizontalAlignments.choices,
+        max_length=10,
+        default=HorizontalAlignments.LEFT,
+    )
+    table_cell_vertical_padding = models.SmallIntegerField(
+        default=10, help_text="Table cell vertical padding"
+    )
+    table_cell_horizontal_padding = models.SmallIntegerField(
+        default=20, help_text="Table cell horizontal padding"
+    )
+
+    # Separator styles
+    table_vertical_separator_color = models.CharField(
+        max_length=20,
+        default="#000000FF",
+        blank=True,
+        help_text="The color of the table vertical separator",
+    )
+    table_vertical_separator_size = models.SmallIntegerField(
+        default=0, help_text="Table vertical separator size"
+    )
+
+    table_horizontal_separator_color = models.CharField(
+        max_length=20,
+        default="#000000FF",
+        blank=True,
+        help_text="The color of the table horizontal separator",
+    )
+    table_horizontal_separator_size = models.SmallIntegerField(
+        default=1, help_text="Table horizontal separator size"
+    )
diff --git a/backend/src/baserow/contrib/builder/theme/theme_config_block_types.py b/backend/src/baserow/contrib/builder/theme/theme_config_block_types.py
index ed8b0e886..2056fdf21 100644
--- a/backend/src/baserow/contrib/builder/theme/theme_config_block_types.py
+++ b/backend/src/baserow/contrib/builder/theme/theme_config_block_types.py
@@ -9,6 +9,7 @@ from .models import (
     InputThemeConfigBlock,
     LinkThemeConfigBlock,
     PageThemeConfigBlock,
+    TableThemeConfigBlock,
     ThemeConfigBlock,
     TypographyThemeConfigBlock,
 )
@@ -153,3 +154,8 @@ class PageThemeConfigBlockType(ThemeConfigBlockType):
 class InputThemeConfigBlockType(ThemeConfigBlockType):
     type = "input"
     model_class = InputThemeConfigBlock
+
+
+class TableThemeConfigBlockType(ThemeConfigBlockType):
+    type = "table"
+    model_class = TableThemeConfigBlock
diff --git a/backend/tests/baserow/contrib/builder/test_builder_application_type.py b/backend/tests/baserow/contrib/builder/test_builder_application_type.py
index 8361e27d5..ae5878b30 100644
--- a/backend/tests/baserow/contrib/builder/test_builder_application_type.py
+++ b/backend/tests/baserow/contrib/builder/test_builder_application_type.py
@@ -572,6 +572,23 @@ def test_builder_application_export(data_fixture):
             "label_font_family": "inter",
             "label_font_size": 13,
             "label_text_color": "#070810FF",
+            "table_border_color": "#000000FF",
+            "table_border_radius": 0,
+            "table_border_size": 1,
+            "table_cell_alternate_background_color": "transparent",
+            "table_cell_background_color": "transparent",
+            "table_cell_horizontal_padding": 20,
+            "table_cell_alignment": "left",
+            "table_cell_vertical_padding": 10,
+            "table_header_background_color": "#edededff",
+            "table_header_font_family": "inter",
+            "table_header_font_size": 13,
+            "table_header_text_alignment": "left",
+            "table_header_text_color": "#000000ff",
+            "table_horizontal_separator_color": "#000000FF",
+            "table_horizontal_separator_size": 1,
+            "table_vertical_separator_color": "#000000FF",
+            "table_vertical_separator_size": 0,
         },
         "id": builder.id,
         "name": builder.name,
@@ -969,6 +986,21 @@ def test_builder_application_export(data_fixture):
             "page_background_color": "#ffffffff",
             "page_background_file_id": None,
             "page_background_mode": "tile",
+            "table_border_size": 1,
+            "table_cell_alternate_background_color": "transparent",
+            "table_cell_background_color": "transparent",
+            "table_cell_horizontal_padding": 20,
+            "table_cell_alignment": "left",
+            "table_cell_vertical_padding": 10,
+            "table_header_background_color": "#edededff",
+            "table_header_font_family": "inter",
+            "table_header_font_size": 13,
+            "table_header_text_alignment": "left",
+            "table_header_text_color": "#000000ff",
+            "table_horizontal_separator_color": "#000000FF",
+            "table_horizontal_separator_size": 0,
+            "table_vertical_separator_color": "#000000FF",
+            "table_vertical_separator_size": 1,
         },
         "user_sources": [
             {
diff --git a/changelog/entries/unreleased/feature/2803_builder_allow_to_style_the_table_element.json b/changelog/entries/unreleased/feature/2803_builder_allow_to_style_the_table_element.json
new file mode 100644
index 000000000..23588f112
--- /dev/null
+++ b/changelog/entries/unreleased/feature/2803_builder_allow_to_style_the_table_element.json
@@ -0,0 +1,7 @@
+{
+    "type": "feature",
+    "message": "[Builder] Allow to style the table element",
+    "issue_number": 2803,
+    "bullet_points": [],
+    "created_at": "2024-07-18"
+}
\ No newline at end of file
diff --git a/web-frontend/modules/builder/components/elements/components/BaserowTable.vue b/web-frontend/modules/builder/components/elements/components/BaserowTable.vue
index 217eb0594..2b704713e 100644
--- a/web-frontend/modules/builder/components/elements/components/BaserowTable.vue
+++ b/web-frontend/modules/builder/components/elements/components/BaserowTable.vue
@@ -30,19 +30,22 @@
                 :field="field"
                 :row-index="index"
               >
-                {{ value }}
+                {{ row[field.name] }}
               </slot>
             </td>
           </tr>
         </tbody>
       </template>
       <template v-else>
-        <tbody v-if="rows.length">
-          <template v-for="(row, rowIndex) in rows">
+        <template v-if="rows.length">
+          <tbody
+            v-for="(row, rowIndex) in rows"
+            :key="row.__id__"
+            class="baserow-table__row"
+          >
             <tr
               v-for="(field, fieldIndex) in fields"
               :key="`${row.__id__}_${field.id}`"
-              class="baserow-table__row"
             >
               <th
                 class="baserow-table__header-cell"
@@ -68,8 +71,8 @@
                 </slot>
               </td>
             </tr>
-          </template>
-        </tbody>
+          </tbody>
+        </template>
       </template>
       <tbody v-if="!rows.length">
         <tr>
diff --git a/web-frontend/modules/builder/components/elements/components/TableElement.vue b/web-frontend/modules/builder/components/elements/components/TableElement.vue
index 955cacd0a..d66e9302d 100644
--- a/web-frontend/modules/builder/components/elements/components/TableElement.vue
+++ b/web-frontend/modules/builder/components/elements/components/TableElement.vue
@@ -4,6 +4,8 @@
       :fields="element.fields"
       :rows="rows"
       :orientation="orientation"
+      class="ab-table"
+      :style="getStyleOverride('table')"
     >
       <template #cell-content="{ rowIndex, field, value }">
         <component
diff --git a/web-frontend/modules/builder/components/elements/components/forms/general/TableElementForm.vue b/web-frontend/modules/builder/components/elements/components/forms/general/TableElementForm.vue
index d73e94c72..dca5e2c82 100644
--- a/web-frontend/modules/builder/components/elements/components/forms/general/TableElementForm.vue
+++ b/web-frontend/modules/builder/components/elements/components/forms/general/TableElementForm.vue
@@ -1,5 +1,11 @@
 <template>
   <form class="table-element-form" @submit.prevent @keydown.enter.prevent>
+    <CustomStyle
+      v-model="values.styles"
+      style-key="table"
+      :config-block-types="['table']"
+      :theme="builder.theme"
+    />
     <FormGroup
       class="margin-bottom-2"
       small-label
diff --git a/web-frontend/modules/builder/components/theme/InputThemeConfigBlock.vue b/web-frontend/modules/builder/components/theme/InputThemeConfigBlock.vue
index 5435f201f..bf81f2140 100644
--- a/web-frontend/modules/builder/components/theme/InputThemeConfigBlock.vue
+++ b/web-frontend/modules/builder/components/theme/InputThemeConfigBlock.vue
@@ -335,44 +335,17 @@ export default {
     },
   },
   validations: {
-    values: {
-      label_font_size: {
-        required,
-        integer,
-        minValue: minValue(minMax.label_font_size.min),
-        maxValue: maxValue(minMax.label_font_size.max),
-      },
-      input_font_size: {
-        required,
-        integer,
-        minValue: minValue(minMax.input_font_size.min),
-        maxValue: maxValue(minMax.input_font_size.max),
-      },
-      input_border_radius: {
-        required,
-        integer,
-        minValue: minValue(minMax.input_border_radius.min),
-        maxValue: maxValue(minMax.input_border_radius.max),
-      },
-      input_border_size: {
-        required,
-        integer,
-        minValue: minValue(minMax.input_border_size.min),
-        maxValue: maxValue(minMax.input_border_size.max),
-      },
-      input_horizontal_padding: {
-        required,
-        integer,
-        minValue: minValue(minMax.input_horizontal_padding.min),
-        maxValue: maxValue(minMax.input_horizontal_padding.max),
-      },
-      input_vertical_padding: {
-        required,
-        integer,
-        minValue: minValue(minMax.input_vertical_padding.min),
-        maxValue: maxValue(minMax.input_vertical_padding.max),
-      },
-    },
+    values: Object.fromEntries(
+      Object.entries(minMax).map(([key, limits]) => [
+        key,
+        {
+          required,
+          integer,
+          minValue: minValue(limits.min),
+          maxValue: maxValue(limits.max),
+        },
+      ])
+    ),
   },
 }
 </script>
diff --git a/web-frontend/modules/builder/components/theme/TableThemeConfigBlock.vue b/web-frontend/modules/builder/components/theme/TableThemeConfigBlock.vue
new file mode 100644
index 000000000..759578fd1
--- /dev/null
+++ b/web-frontend/modules/builder/components/theme/TableThemeConfigBlock.vue
@@ -0,0 +1,432 @@
+<template>
+  <div>
+    <ThemeConfigBlockSection :title="$t('tableThemeConfigBlock.table')">
+      <template #default>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.borderSize')"
+          :error-message="getError('table_border_size')"
+          class="margin-bottom-2"
+        >
+          <PixelValueSelector v-model="values.table_border_size" />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_border_size"
+              :default-value="theme?.table_border_size"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          required
+          :label="$t('tableThemeConfigBlock.borderColor')"
+          class="margin-bottom-2"
+        >
+          <ColorInput
+            v-model="values.table_border_color"
+            :color-variables="colorVariables"
+            :default-value="theme?.table_border_color"
+            small
+          />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_border_color"
+              :default-value="theme?.table_border_color"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.borderRadius')"
+          :error-message="getError('table_border_radius')"
+          class="margin-bottom-2"
+        >
+          <PixelValueSelector v-model="values.table_border_radius" />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_border_radius"
+              :default-value="theme?.table_border_radius"
+            />
+          </template>
+        </FormGroup>
+      </template>
+      <template #preview>
+        <BaserowTable :fields="fields" :rows="rows" class="ab-table">
+        </BaserowTable>
+      </template>
+    </ThemeConfigBlockSection>
+
+    <ThemeConfigBlockSection :title="$t('tableThemeConfigBlock.header')">
+      <template #default>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.backgroundColor')"
+          class="margin-bottom-2"
+        >
+          <ColorInput
+            v-model="values.table_header_background_color"
+            :color-variables="colorVariables"
+            :default-value="theme?.table_header_background_color"
+            small
+          />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_header_background_color"
+              :default-value="theme?.table_header_background_color"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.fontFamily')"
+          class="margin-bottom-2"
+        >
+          <FontFamilySelector v-model="values.table_header_font_family" />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_header_font_family"
+              :default-value="theme?.table_header_font_family"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.fontSize')"
+          :error-message="getError('table_header_font_size')"
+          class="margin-bottom-2"
+        >
+          <PixelValueSelector v-model="values.table_header_font_size" />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_header_font_size"
+              :default-value="theme?.table_header_font_size"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.textColor')"
+          class="margin-bottom-2"
+        >
+          <ColorInput
+            v-model="values.table_header_text_color"
+            :color-variables="colorVariables"
+            :default-value="theme?.table_header_text_color"
+            small
+          />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_header_text_color"
+              :default-value="theme?.table_header_text_color"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          required
+          :label="$t('tableThemeConfigBlock.alignment')"
+          class="margin-bottom-2"
+        >
+          <HorizontalAlignmentsSelector
+            v-model="values.table_header_text_alignment"
+          />
+
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_header_text_alignment"
+              :default-value="theme?.table_header_text_alignment"
+            />
+          </template>
+        </FormGroup>
+      </template>
+      <template #preview>
+        <BaserowTable :fields="fields" :rows="rows" class="ab-table">
+        </BaserowTable>
+      </template>
+    </ThemeConfigBlockSection>
+
+    <ThemeConfigBlockSection :title="$t('tableThemeConfigBlock.cells')">
+      <template #default>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.backgroundColor')"
+          class="margin-bottom-2"
+        >
+          <ColorInput
+            v-model="values.table_cell_background_color"
+            :color-variables="colorVariables"
+            :default-value="theme?.table_cell_background_color"
+            small
+          />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_cell_background_color"
+              :default-value="theme?.table_cell_background_color"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.backgroundAlternateColor')"
+          class="margin-bottom-2"
+        >
+          <ColorInput
+            v-model="values.table_cell_alternate_background_color"
+            :color-variables="colorVariables"
+            :default-value="theme?.table_cell_alternate_background_color"
+            small
+          />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_cell_alternate_background_color"
+              :default-value="theme?.table_cell_alternate_background_color"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          required
+          :label="$t('tableThemeConfigBlock.alignment')"
+          class="margin-bottom-2"
+        >
+          <HorizontalAlignmentsSelector v-model="values.table_cell_alignment" />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_cell_alignment"
+              :default-value="theme?.table_cell_alignment"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.padding')"
+          :error-message="getPaddingError()"
+          class="margin-bottom-2"
+        >
+          <PaddingSelector v-model="padding" />
+          <template #after-input>
+            <ResetButton
+              v-model="padding"
+              :default-value="
+                theme
+                  ? {
+                      vertical: theme['table_cell_vertical_padding'],
+                      horizontal: theme['table_cell_horizontal_padding'],
+                    }
+                  : undefined
+              "
+            />
+          </template>
+        </FormGroup>
+      </template>
+      <template #preview>
+        <BaserowTable :fields="fields" :rows="rows" class="ab-table">
+        </BaserowTable>
+      </template>
+    </ThemeConfigBlockSection>
+    <ThemeConfigBlockSection :title="$t('tableThemeConfigBlock.separators')">
+      <template #default>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.horizontalSeparatorColor')"
+          class="margin-bottom-2"
+        >
+          <ColorInput
+            v-model="values.table_horizontal_separator_color"
+            :color-variables="colorVariables"
+            :default-value="theme?.table_horizontal_separator_color"
+            small
+          />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_horizontal_separator_color"
+              :default-value="theme?.table_horizontal_separator_color"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.horizontalSeparatorSize')"
+          :error-message="getError('table_horizontal_separator_size')"
+          class="margin-bottom-2"
+        >
+          <PixelValueSelector
+            v-model="values.table_horizontal_separator_size"
+          />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_horizontal_separator_size"
+              :default-value="theme?.table_horizontal_separator_size"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.verticalSeparatorColor')"
+          class="margin-bottom-2"
+        >
+          <ColorInput
+            v-model="values.table_vertical_separator_color"
+            :color-variables="colorVariables"
+            :default-value="theme?.table_vertical_separator_color"
+            small
+          />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_vertical_separator_color"
+              :default-value="theme?.table_vertical_separator_color"
+            />
+          </template>
+        </FormGroup>
+        <FormGroup
+          horizontal-narrow
+          small-label
+          :label="$t('tableThemeConfigBlock.verticalSeparatorSize')"
+          :error-message="getError('table_vertical_separator_size')"
+          class="margin-bottom-2"
+        >
+          <PixelValueSelector v-model="values.table_vertical_separator_size" />
+          <template #after-input>
+            <ResetButton
+              v-model="values.table_vertical_separator_size"
+              :default-value="theme?.table_vertical_separator_size"
+            />
+          </template>
+        </FormGroup>
+      </template>
+      <template #preview>
+        <BaserowTable :fields="fields" :rows="rows" class="ab-table">
+        </BaserowTable>
+      </template>
+    </ThemeConfigBlockSection>
+  </div>
+</template>
+
+<script>
+import themeConfigBlock from '@baserow/modules/builder/mixins/themeConfigBlock'
+import ThemeConfigBlockSection from '@baserow/modules/builder/components/theme/ThemeConfigBlockSection'
+import ResetButton from '@baserow/modules/builder/components/theme/ResetButton'
+import HorizontalAlignmentsSelector from '@baserow/modules/builder/components/HorizontalAlignmentsSelector'
+import FontFamilySelector from '@baserow/modules/builder/components/FontFamilySelector'
+import PixelValueSelector from '@baserow/modules/builder/components/PixelValueSelector'
+import PaddingSelector from '@baserow/modules/builder/components/PaddingSelector'
+import { required, integer, minValue, maxValue } from 'vuelidate/lib/validators'
+import BaserowTable from '@baserow/modules/builder/components/elements/components/BaserowTable'
+
+const minMax = {
+  table_border_size: {
+    min: 0,
+    max: 30,
+  },
+  table_border_radius: {
+    min: 0,
+    max: 100,
+  },
+  table_header_font_size: {
+    min: 1,
+    max: 100,
+  },
+  table_cell_vertical_padding: {
+    min: 0,
+    max: 100,
+  },
+  table_cell_horizontal_padding: {
+    min: 0,
+    max: 100,
+  },
+  table_horizontal_separator_size: {
+    min: 0,
+    max: 100,
+  },
+  table_vertical_separator_size: {
+    min: 0,
+    max: 100,
+  },
+}
+
+export default {
+  name: 'ButtonThemeConfigBlock',
+  components: {
+    ThemeConfigBlockSection,
+    ResetButton,
+    BaserowTable,
+    HorizontalAlignmentsSelector,
+    FontFamilySelector,
+    PixelValueSelector,
+    PaddingSelector,
+  },
+  mixins: [themeConfigBlock],
+  data() {
+    return {
+      values: {},
+      fields: [
+        { __id__: 1, id: 1, name: 'Header 1' },
+        { __id__: 2, id: 2, name: 'Header 2' },
+      ],
+      rows: [
+        { 'Header 1': 'Row 1 cell 1', 'Header 2': 'Row 1 cell 2' },
+        { 'Header 1': 'Row 2 cell 1', 'Header 2': 'Row 2 cell 2' },
+      ],
+    }
+  },
+  computed: {
+    padding: {
+      get() {
+        return {
+          vertical: this.values.table_cell_vertical_padding,
+          horizontal: this.values.table_cell_horizontal_padding,
+        }
+      },
+      set(newValue) {
+        this.values.table_cell_vertical_padding = newValue.vertical
+        this.values.table_cell_horizontal_padding = newValue.horizontal
+      },
+    },
+  },
+  methods: {
+    isAllowedKey(key) {
+      return key.startsWith('table_')
+    },
+    getError(property) {
+      if (this.$v.values[property].$invalid) {
+        return this.$t('error.minMaxValueField', minMax[property])
+      }
+      return null
+    },
+    getPaddingError() {
+      return (
+        this.getError('table_cell_vertical_padding') ||
+        this.getError('table_cell_horizontal_padding')
+      )
+    },
+  },
+  validations: {
+    values: Object.fromEntries(
+      Object.entries(minMax).map(([key, limits]) => [
+        key,
+        {
+          required,
+          integer,
+          minValue: minValue(limits.min),
+          maxValue: maxValue(limits.max),
+        },
+      ])
+    ),
+  },
+}
+</script>
diff --git a/web-frontend/modules/builder/locales/en.json b/web-frontend/modules/builder/locales/en.json
index af78bd2e4..7ce095fa1 100644
--- a/web-frontend/modules/builder/locales/en.json
+++ b/web-frontend/modules/builder/locales/en.json
@@ -379,7 +379,8 @@
     "button": "Button",
     "link": "Link",
     "image": "Image",
-    "input": "Input"
+    "input": "Input",
+    "table": "Table"
   },
   "colorThemeConfigBlock": {
     "primaryColor": "Primary",
@@ -395,6 +396,7 @@
     "backgroundMode": "Background mode"
   },
   "colorThemeConfigBlockType": {
+    "transparent": "Transparent",
     "primary": "Primary",
     "secondary": "Secondary",
     "border": "Border",
@@ -460,6 +462,27 @@
     "imageConstraintContain": "Contain",
     "imageConstraintContainDisabled": "Unavailable with a max height."
   },
+  "tableThemeConfigBlock": {
+    "borderColor": "Border color",
+    "backgroundAlternateColor": "Alternate color",
+    "backgroundColor": "Background color",
+    "textColor": "Text color",
+    "borderSize": "Border size",
+    "borderRadius": "Border radius",
+    "padding": "Padding",
+    "fontFamily": "Font",
+    "size": "Size",
+    "fontSize": "Font size",
+    "table": "Table",
+    "header": "Header",
+    "alignment": "Alignment",
+    "cells": "Cells",
+    "separators": "Separators",
+    "verticalSeparatorColor": "Vertical color",
+    "verticalSeparatorSize": "Vertical size",
+    "horizontalSeparatorColor": "Horizontal color",
+    "horizontalSeparatorSize": "Horizontal size"
+  },
   "buttonElementForm": {
     "valueLabel": "Button text",
     "valuePlaceholder": "Enter text..."
diff --git a/web-frontend/modules/builder/plugin.js b/web-frontend/modules/builder/plugin.js
index 193b86415..2f80cde67 100644
--- a/web-frontend/modules/builder/plugin.js
+++ b/web-frontend/modules/builder/plugin.js
@@ -93,6 +93,7 @@ import {
   ImageThemeConfigBlockType,
   PageThemeConfigBlockType,
   InputThemeConfigBlockType,
+  TableThemeConfigBlockType,
 } from '@baserow/modules/builder/themeConfigBlockTypes'
 import {
   CreateRowWorkflowActionType,
@@ -297,6 +298,10 @@ export default (context) => {
     'themeConfigBlock',
     new InputThemeConfigBlockType(context)
   )
+  app.$registry.register(
+    'themeConfigBlock',
+    new TableThemeConfigBlockType(context)
+  )
 
   app.$registry.register(
     'workflowAction',
diff --git a/web-frontend/modules/builder/themeConfigBlockTypes.js b/web-frontend/modules/builder/themeConfigBlockTypes.js
index caf0e82c9..50fdfa7fb 100644
--- a/web-frontend/modules/builder/themeConfigBlockTypes.js
+++ b/web-frontend/modules/builder/themeConfigBlockTypes.js
@@ -6,6 +6,7 @@ import LinkThemeConfigBlock from '@baserow/modules/builder/components/theme/Link
 import ImageThemeConfigBlock from '@baserow/modules/builder/components/theme/ImageThemeConfigBlock'
 import PageThemeConfigBlock from '@baserow/modules/builder/components/theme/PageThemeConfigBlock'
 import InputThemeConfigBlock from '@baserow/modules/builder/components/theme/InputThemeConfigBlock'
+import TableThemeConfigBlock from '@baserow/modules/builder/components/theme/TableThemeConfigBlock'
 import {
   resolveColor,
   colorRecommendation,
@@ -21,16 +22,52 @@ import get from 'lodash/get'
  * Helper class to construct easily style objects.
  */
 export class ThemeStyle {
-  constructor() {
+  constructor({ colorVariables = {}, $registry }) {
     this.style = {}
+    this.colorVariables = colorVariables
+    this.$registry = $registry
   }
 
   addIfExists(theme, propName, styleName, transform = (v) => v) {
+    if (!styleName) {
+      styleName = `--${propName.replace(/_/g, '-')}`
+    }
     if (Object.prototype.hasOwnProperty.call(theme, propName)) {
       this.style[styleName] = transform(theme[propName])
     }
   }
 
+  addColorIfExists(theme, propName, styleName) {
+    return this.addIfExists(theme, propName, styleName, (v) =>
+      resolveColor(v, this.colorVariables)
+    )
+  }
+
+  addColorRecommendationIfExists(theme, propName, styleName) {
+    return this.addIfExists(
+      theme,
+      propName,
+      styleName,
+      (v) => (v) => colorRecommendation(resolveColor(v, this.colorVariables))
+    )
+  }
+
+  addFontFamilyIfExists(theme, propName, styleName) {
+    return this.addIfExists(theme, propName, styleName, (v) => {
+      const fontFamilyType = this.$registry.get('fontFamily', v)
+      return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"`
+    })
+  }
+
+  addPixelValueIfExists(theme, propName, styleName) {
+    return this.addIfExists(
+      theme,
+      propName,
+      styleName,
+      (v) => `${Math.min(100, v)}px`
+    )
+  }
+
   toObject() {
     return this.style
   }
@@ -124,7 +161,10 @@ export class ColorThemeConfigBlockType extends ThemeConfigBlockType {
   }
 
   getCSS(theme, colorVariables, baseTheme = null) {
-    const style = new ThemeStyle()
+    const style = new ThemeStyle({
+      colorVariables,
+      $registry: this.app.$registry,
+    })
     style.addIfExists(theme, 'primary_color', '--main-primary-color', (v) =>
       resolveColor(v, colorVariables)
     )
@@ -155,6 +195,11 @@ export class ColorThemeConfigBlockType extends ThemeConfigBlockType {
   getColorVariables(theme) {
     const { i18n } = this.app
     return [
+      {
+        name: i18n.t('colorThemeConfigBlockType.transparent'),
+        value: 'transparent',
+        color: '#00000000',
+      },
       {
         name: i18n.t('colorThemeConfigBlockType.primary'),
         value: 'primary',
@@ -207,15 +252,17 @@ export class TypographyThemeConfigBlockType extends ThemeConfigBlockType {
   }
 
   getCSS(theme, colorVariables, baseTheme = null) {
-    const style = new ThemeStyle()
+    const style = new ThemeStyle({
+      colorVariables,
+      $registry: this.app.$registry,
+    })
     Array.from([1, 2, 3, 4, 5, 6]).forEach((level) => {
-      style.addIfExists(
+      style.addPixelValueIfExists(
         theme,
         `heading_${level}_font_size`,
-        `--heading-h${level}-font-size`,
-        (v) => `${Math.min(100, v)}px`
+        `--heading-h${level}-font-size`
       )
-      style.addIfExists(
+      style.addColorIfExists(
         theme,
         `heading_${level}_text_color`,
         `--heading-h${level}-color`,
@@ -224,38 +271,18 @@ export class TypographyThemeConfigBlockType extends ThemeConfigBlockType {
       style.addIfExists(
         theme,
         `heading_${level}_text_alignment`,
-        `--heading-h${level}-text-alignment`,
-        (v) => v
+        `--heading-h${level}-text-alignment`
       )
-      style.addIfExists(
+      style.addFontFamilyIfExists(
         theme,
         `heading_${level}_font_family`,
-        `--heading-h${level}-font-family`,
-        (v) => {
-          const fontFamilyType = this.app.$registry.get('fontFamily', v)
-          return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"`
-        }
+        `--heading-h${level}-font-family`
       )
     })
-    style.addIfExists(
-      theme,
-      `body_font_size`,
-      `--body-font-size`,
-      (v) => `${Math.min(100, v)}px`
-    )
-    style.addIfExists(theme, `body_text_color`, `--body-text-color`, (v) =>
-      resolveColor(v, colorVariables)
-    )
-    style.addIfExists(
-      theme,
-      `body_text_alignment`,
-      `--body-text-alignment`,
-      (v) => v
-    )
-    style.addIfExists(theme, `body_font_family`, `--body-font-family`, (v) => {
-      const fontFamilyType = this.app.$registry.get('fontFamily', v)
-      return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"`
-    })
+    style.addPixelValueIfExists(theme, `body_font_size`)
+    style.addColorIfExists(theme, `body_text_color`)
+    style.addIfExists(theme, `body_text_alignment`)
+    style.addFontFamilyIfExists(theme, `body_font_family`)
     return style.toObject()
   }
 
@@ -278,53 +305,24 @@ export class ButtonThemeConfigBlockType extends ThemeConfigBlockType {
   }
 
   getCSS(theme, colorVariables, baseTheme = null) {
-    const style = new ThemeStyle()
-    style.addIfExists(
-      theme,
-      'button_background_color',
-      '--button-background-color',
-      (v) => resolveColor(v, colorVariables)
-    )
-    style.addIfExists(
-      theme,
-      'button_hover_background_color',
-      '--button-hover-background-color',
-      (v) => resolveColor(v, colorVariables)
-    )
-    style.addIfExists(theme, 'button_text_color', '--button-text-color', (v) =>
-      resolveColor(v, colorVariables)
-    )
-    style.addIfExists(
-      theme,
-      'button_hover_text_color',
-      '--button-hover-text-color',
-      (v) => resolveColor(v, colorVariables)
-    )
-    style.addIfExists(
-      theme,
-      'button_border_color',
-      '--button-border-color',
-      (v) => resolveColor(v, colorVariables)
-    )
-    style.addIfExists(
-      theme,
-      'button_hover_border_color',
-      '--button-hover-border-color',
-      (v) => resolveColor(v, colorVariables)
-    )
-    style.addIfExists(theme, 'button_width', '--button-width', (v) =>
+    const style = new ThemeStyle({
+      colorVariables,
+      $registry: this.app.$registry,
+    })
+    style.addColorIfExists(theme, 'button_background_color')
+    style.addColorIfExists(theme, 'button_hover_background_color')
+    style.addColorIfExists(theme, 'button_text_color')
+    style.addColorIfExists(theme, 'button_hover_text_color')
+    style.addColorIfExists(theme, 'button_border_color')
+    style.addColorIfExists(theme, 'button_hover_border_color')
+    style.addIfExists(theme, 'button_width', null, (v) =>
       v === WIDTHS_NEW.FULL ? '100%' : 'auto'
     )
-    style.addIfExists(
-      theme,
-      'button_text_alignment',
-      '--button-text-alignment',
-      (v) => v
-    )
+    style.addIfExists(theme, 'button_text_alignment')
     style.addIfExists(
       theme,
       'button_alignment',
-      '--button-alignment',
+      null,
       (v) =>
         ({
           [HORIZONTAL_ALIGNMENTS.LEFT]: 'flex-start',
@@ -332,51 +330,12 @@ export class ButtonThemeConfigBlockType extends ThemeConfigBlockType {
           [HORIZONTAL_ALIGNMENTS.RIGHT]: 'flex-end',
         }[v])
     )
-    style.addIfExists(
-      theme,
-      'button_font_alignment',
-      '--button-text-alignment',
-      (v) => v
-    )
-    style.addIfExists(
-      theme,
-      `button_font_family`,
-      `--button-font-family`,
-      (v) => {
-        const fontFamilyType = this.app.$registry.get('fontFamily', v)
-        return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"`
-      }
-    )
-    style.addIfExists(
-      theme,
-      `button_font_size`,
-      `--button-font-size`,
-      (v) => `${Math.min(100, v)}px`
-    )
-    style.addIfExists(
-      theme,
-      `button_border_radius`,
-      `--button-border-radius`,
-      (v) => `${v}px`
-    )
-    style.addIfExists(
-      theme,
-      `button_border_size`,
-      `--button-border-size`,
-      (v) => `${v}px`
-    )
-    style.addIfExists(
-      theme,
-      `button_horizontal_padding`,
-      `--button-horizontal-padding`,
-      (v) => `${v}px`
-    )
-    style.addIfExists(
-      theme,
-      `button_vertical_padding`,
-      `--button-vertical-padding`,
-      (v) => `${v}px`
-    )
+    style.addFontFamilyIfExists(theme, `button_font_family`)
+    style.addPixelValueIfExists(theme, `button_font_size`)
+    style.addPixelValueIfExists(theme, `button_border_radius`)
+    style.addPixelValueIfExists(theme, `button_border_size`)
+    style.addPixelValueIfExists(theme, `button_horizontal_padding`)
+    style.addPixelValueIfExists(theme, `button_vertical_padding`)
     return style.toObject()
   }
 
@@ -399,16 +358,12 @@ export class LinkThemeConfigBlockType extends ThemeConfigBlockType {
   }
 
   getCSS(theme, colorVariables, baseTheme = null) {
-    const style = new ThemeStyle()
-    style.addIfExists(theme, 'link_text_color', '--link-text-color', (v) =>
-      resolveColor(v, colorVariables)
-    )
-    style.addIfExists(
-      theme,
-      'link_hover_text_color',
-      '--link-hover-text-color',
-      (v) => resolveColor(v, colorVariables)
-    )
+    const style = new ThemeStyle({
+      colorVariables,
+      $registry: this.app.$registry,
+    })
+    style.addColorIfExists(theme, 'link_text_color')
+    style.addColorIfExists(theme, 'link_hover_text_color')
     style.addIfExists(
       theme,
       'link_text_alignment',
@@ -446,7 +401,10 @@ export class ImageThemeConfigBlockType extends ThemeConfigBlockType {
   }
 
   getCSS(theme, colorVariables, baseTheme = null) {
-    const style = new ThemeStyle()
+    const style = new ThemeStyle({
+      colorVariables,
+      $registry: this.app.$registry,
+    })
     style.addIfExists(
       theme,
       'image_alignment',
@@ -532,13 +490,11 @@ export class PageThemeConfigBlockType extends ThemeConfigBlockType {
   }
 
   getCSS(theme, colorVariables, baseTheme = null) {
-    const style = new ThemeStyle()
-    style.addIfExists(
-      theme,
-      'page_background_color',
-      '--page-background-color',
-      (v) => resolveColor(v, colorVariables)
-    )
+    const style = new ThemeStyle({
+      colorVariables,
+      $registry: this.app.$registry,
+    })
+    style.addColorIfExists(theme, 'page_background_color')
     style.addIfExists(
       theme,
       'page_background_file',
@@ -579,98 +535,40 @@ export class InputThemeConfigBlockType extends ThemeConfigBlockType {
   }
 
   getCSS(theme, colorVariables, baseTheme = null) {
-    const style = new ThemeStyle()
-    style.addIfExists(theme, 'label_text_color', '--label-text-color', (v) =>
-      resolveColor(v, colorVariables)
-    )
-    style.addIfExists(
-      theme,
-      `label_font_family`,
-      `--label-font-family`,
-      (v) => {
-        const fontFamilyType = this.app.$registry.get('fontFamily', v)
-        return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"`
-      }
-    )
-    style.addIfExists(
-      theme,
-      `label_font_size`,
-      `--label-font-size`,
-      (v) => `${Math.min(100, v)}px`
-    )
+    const style = new ThemeStyle({
+      colorVariables,
+      $registry: this.app.$registry,
+    })
 
-    style.addIfExists(theme, 'input_text_color', '--input-text-color', (v) =>
-      resolveColor(v, colorVariables)
-    )
+    style.addColorIfExists(theme, 'label_text_color')
+    style.addFontFamilyIfExists(theme, `label_font_family`)
+    style.addPixelValueIfExists(theme, `label_font_size`)
+
+    style.addColorIfExists(theme, 'input_text_color')
     style.addIfExists(
       theme,
       'input_text_color',
       '--input-text-color-complement',
       (v) => colorRecommendation(resolveColor(v, colorVariables))
     )
-    style.addIfExists(
-      theme,
-      `input_font_family`,
-      `--input-font-family`,
-      (v) => {
-        const fontFamilyType = this.app.$registry.get('fontFamily', v)
-        return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"`
-      }
-    )
-    style.addIfExists(
-      theme,
-      `input_font_size`,
-      `--input-font-size`,
-      (v) => `${Math.min(100, v)}px`
-    )
-    style.addIfExists(
+    style.addFontFamilyIfExists(theme, `input_font_family`)
+    style.addPixelValueIfExists(theme, `input_font_size`)
+    style.addColorIfExists(theme, 'input_background_color')
+    style.addColorRecommendationIfExists(
       theme,
       'input_background_color',
-      '--input-background-color',
-      (v) => resolveColor(v, colorVariables)
+      '--input-background-color-complement'
     )
-    style.addIfExists(
-      theme,
-      'input_background_color',
-      '--input-background-color-complement',
-      (v) => colorRecommendation(resolveColor(v, colorVariables))
-    )
-    style.addIfExists(
+    style.addColorIfExists(theme, 'input_border_color')
+    style.addColorRecommendationIfExists(
       theme,
       'input_border_color',
-      '--input-border-color',
-      (v) => resolveColor(v, colorVariables)
-    )
-    style.addIfExists(
-      theme,
-      'input_border_color',
-      '--input-border-color-complement',
-      (v) => colorRecommendation(resolveColor(v, colorVariables))
-    )
-    style.addIfExists(
-      theme,
-      `input_border_radius`,
-      `--input-border-radius`,
-      (v) => `${v}px`
-    )
-    style.addIfExists(
-      theme,
-      `input_border_size`,
-      `--input-border-size`,
-      (v) => `${v}px`
-    )
-    style.addIfExists(
-      theme,
-      `input_horizontal_padding`,
-      `--input-horizontal-padding`,
-      (v) => `${v}px`
-    )
-    style.addIfExists(
-      theme,
-      `input_vertical_padding`,
-      `--input-vertical-padding`,
-      (v) => `${v}px`
+      '--input-border-color-complement'
     )
+    style.addPixelValueIfExists(theme, `input_border_radius`)
+    style.addPixelValueIfExists(theme, `input_border_size`)
+    style.addPixelValueIfExists(theme, `input_horizontal_padding`)
+    style.addPixelValueIfExists(theme, `input_vertical_padding`)
     return style.toObject()
   }
 
@@ -682,3 +580,53 @@ export class InputThemeConfigBlockType extends ThemeConfigBlockType {
     return 55
   }
 }
+
+export class TableThemeConfigBlockType extends ThemeConfigBlockType {
+  static getType() {
+    return 'table'
+  }
+
+  get label() {
+    return this.app.i18n.t('themeConfigBlockType.table')
+  }
+
+  getCSS(theme, colorVariables, baseTheme = null) {
+    const style = new ThemeStyle({
+      colorVariables,
+      $registry: this.app.$registry,
+    })
+    style.addColorIfExists(theme, 'table_border_color')
+    style.addPixelValueIfExists(theme, `table_border_size`)
+    style.addPixelValueIfExists(theme, `table_border_radius`)
+
+    style.addColorIfExists(theme, 'table_header_background_color')
+    style.addColorIfExists(theme, 'table_header_text_color')
+    style.addPixelValueIfExists(theme, `table_header_font_size`)
+    style.addFontFamilyIfExists(theme, `table_header_font_family`)
+    style.addIfExists(theme, `table_header_text_alignment`)
+
+    style.addColorIfExists(theme, 'table_cell_background_color')
+    style.addColorIfExists(theme, 'table_cell_alternate_background_color')
+    style.addColorIfExists(theme, 'table_cell_text_color')
+    style.addFontFamilyIfExists(theme, `table_cell_font_family`)
+    style.addPixelValueIfExists(theme, `table_cell_font_size`)
+    style.addIfExists(theme, `table_cell_alignment`)
+    style.addPixelValueIfExists(theme, `table_cell_vertical_padding`)
+    style.addPixelValueIfExists(theme, `table_cell_horizontal_padding`)
+
+    style.addColorIfExists(theme, 'table_vertical_separator_color')
+    style.addPixelValueIfExists(theme, `table_vertical_separator_size`)
+    style.addColorIfExists(theme, 'table_horizontal_separator_color')
+    style.addPixelValueIfExists(theme, `table_horizontal_separator_size`)
+
+    return style.toObject()
+  }
+
+  get component() {
+    return TableThemeConfigBlock
+  }
+
+  getOrder() {
+    return 65
+  }
+}
diff --git a/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/ab_table.scss b/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/ab_table.scss
new file mode 100644
index 000000000..f275b42b8
--- /dev/null
+++ b/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/ab_table.scss
@@ -0,0 +1,81 @@
+.ab-table {
+  border: var(--table-border-size, 1px) solid var(--table-border-color, $black);
+  text-align: var(--table-cell-alignment, left);
+  font-size: var(--body-font-size, 13px);
+  border-radius: var(--table-border-radius, 0);
+  background-color: var(--table-cell-background-color, $palette-neutral-200);
+
+  .baserow-table__header-cell,
+  .baserow-table__cell {
+    padding: var(--table-cell-vertical-padding, 10px)
+      var(--table-cell-horizontal-padding, 20px);
+  }
+
+  .baserow-table__cell {
+    font-size: var(--body-font-size, 13px);
+    color: var(--body-text-color, $color-neutral-900);
+    font-family: var(--body-font-family, Inter);
+    text-align: var(--table-cell-alignment, left);
+  }
+
+  .baserow-table__header-cell {
+    font-weight: 600;
+    background-color: var(
+      --table-header-background-color,
+      $palette-neutral-200
+    );
+    font-size: var(--table-header-font-size, 13px);
+    color: var(--table-header-text-color, $color-neutral-900);
+    font-family: var(--table-header-font-family, Inter);
+    text-align: var(--table-header-text-alignment, left);
+  }
+
+  & .baserow-table__row:not(:last-child) .baserow-table__separator {
+    border-bottom: var(--table-horizontal-separator-size, 1px) solid
+      var(--table-horizontal-separator-color, $black);
+  }
+
+  .baserow-table--vertical {
+    .baserow-table__header-cell {
+      border-right: var(--table-vertical-separator-size, 1px) solid
+        var(--table-vertical-separator-color, $black);
+    }
+
+    tbody.baserow-table__row:nth-child(even) {
+      background-color: var(
+        --table-cell-alternate-background-color,
+        transparent
+      );
+    }
+  }
+
+  .baserow-table--horizontal {
+    .baserow-table__header-cell,
+    .baserow-table__cell {
+      border-bottom: var(--table-horizontal-separator-size, 1px) solid
+        var(--table-horizontal-separator-color, $black);
+      border-right: var(--table-vertical-separator-size, 1px) solid
+        var(--table-vertical-separator-color, $black);
+    }
+
+    .baserow-table__row {
+      .baserow-table__cell:last-child,
+      .baserow-table__header-cell:last-child {
+        border-right: none;
+      }
+    }
+
+    .baserow-table__row:last-child {
+      .baserow-table__cell {
+        border-bottom: none;
+      }
+    }
+
+    tbody .baserow-table__row:nth-child(even) {
+      background-color: var(
+        --table-cell-alternate-background-color,
+        transparent
+      );
+    }
+  }
+}
diff --git a/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/all.scss b/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/all.scss
index 078f8c064..0bfbe73e2 100644
--- a/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/all.scss
+++ b/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/all.scss
@@ -10,3 +10,4 @@
 @import 'ab_tag';
 @import 'ab_radio';
 @import 'ab_image';
+@import 'ab_table';
diff --git a/web-frontend/modules/core/assets/scss/components/builder/elements/baserow_table.scss b/web-frontend/modules/core/assets/scss/components/builder/elements/baserow_table.scss
index 5a8afb9a5..09fe7de04 100644
--- a/web-frontend/modules/core/assets/scss/components/builder/elements/baserow_table.scss
+++ b/web-frontend/modules/core/assets/scss/components/builder/elements/baserow_table.scss
@@ -4,41 +4,6 @@
 
 .baserow-table {
   width: 100%;
-  border: 1px solid $black;
   border-spacing: 0;
   text-align: left;
-  font-size: 12px;
-}
-
-.baserow-table__header-cell,
-.baserow-table__cell {
-  padding: 12px 20px 10px;
-}
-
-.baserow-table__header-cell {
-  font-weight: 600;
-  background-color: $palette-neutral-200;
-}
-
-.baserow-table__separator {
-  .baserow-table__row:not(:last-child) & {
-    border-bottom: 1px solid $black;
-  }
-}
-
-.baserow-table--horizontal {
-  .baserow-table__header-cell,
-  .baserow-table__cell {
-    border-bottom: 1px solid $black;
-  }
-
-  .baserow-table__row:last-child .baserow-table__cell {
-    border-bottom: none;
-  }
-}
-
-.baserow-table--vertical {
-  .baserow-table__header-cell {
-    border-right: 1px solid $black;
-  }
 }
diff --git a/web-frontend/modules/core/components/ColorInputGroup.vue b/web-frontend/modules/core/components/ColorInputGroup.vue
deleted file mode 100644
index b5d1e92f5..000000000
--- a/web-frontend/modules/core/components/ColorInputGroup.vue
+++ /dev/null
@@ -1,62 +0,0 @@
-<template>
-  <FormGroup v-if="!labelAfter" small-label required :label="label">
-    <ColorInput
-      :value="value"
-      :color-variables="colorVariables"
-      @input="$emit('input', $event)"
-    />
-    <template #after-input>
-      <slot name="after-input"></slot>
-    </template>
-  </FormGroup>
-  <div v-else class="control">
-    <div class="control__elements">
-      <div class="color-input-group--label-after">
-        <ColorInput
-          :value="value"
-          :color-variables="colorVariables"
-          :horizontal="horizontal"
-          @input="$emit('input', $event)"
-        />
-        <div class="color-input-group__label-after">
-          {{ label }}
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import ColorInput from '@baserow/modules/core/components/ColorInput'
-
-export default {
-  name: 'ColorInputGroup',
-  components: { ColorInput },
-  props: {
-    value: {
-      type: String,
-      required: false,
-      default: 'primary',
-    },
-    label: {
-      type: String,
-      required: true,
-    },
-    labelAfter: {
-      type: Boolean,
-      required: false,
-      default: false,
-    },
-    colorVariables: {
-      type: Array,
-      required: false,
-      default: () => [],
-    },
-    horizontal: {
-      type: Boolean,
-      required: false,
-      default: false,
-    },
-  },
-}
-</script>
diff --git a/web-frontend/modules/core/components/ColorPickerContext.vue b/web-frontend/modules/core/components/ColorPickerContext.vue
index e99d8ebcc..f4bb22076 100644
--- a/web-frontend/modules/core/components/ColorPickerContext.vue
+++ b/web-frontend/modules/core/components/ColorPickerContext.vue
@@ -164,6 +164,13 @@ export default {
   },
   methods: {
     setColorFromPicker(value) {
+      if (this.selectedVariable) {
+        // If we come from a variable before we reset the alpha channel to 1 otherwise
+        // You could think something doesn't work.
+        const rgba = convertHexToRgb(value)
+        rgba.a = 1
+        value = convertRgbToHex(rgba)
+      }
       this.colorUpdated(value)
       this.$emit(
         'input',
diff --git a/web-frontend/modules/core/plugins/global.js b/web-frontend/modules/core/plugins/global.js
index 2ef38e3d4..5b432d6ed 100644
--- a/web-frontend/modules/core/plugins/global.js
+++ b/web-frontend/modules/core/plugins/global.js
@@ -57,7 +57,6 @@ import Expandable from '@baserow/modules/core/components/Expandable.vue'
 import RadioButton from '@baserow/modules/core/components/RadioButton'
 import Thumbnail from '@baserow/modules/core/components/Thumbnail'
 import ColorInput from '@baserow/modules/core/components/ColorInput'
-import ColorInputGroup from '@baserow/modules/core/components/ColorInputGroup'
 import SelectSearch from '@baserow/modules/core/components/SelectSearch'
 
 function setupVue(Vue) {
@@ -101,7 +100,6 @@ function setupVue(Vue) {
   Vue.component('FormGroup', FormGroup)
   Vue.component('FormRow', FormRow)
   Vue.component('ColorInput', ColorInput)
-  Vue.component('ColorInputGroup', ColorInputGroup)
   Vue.component('ImageInput', ImageInput)
   Vue.component('SelectSearch', SelectSearch)
   Vue.component('Logo', Logo)