diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 7b9b9123c3112e7fa28b9539227ad904444a1fe8..fcf3cb05e63eeb5315bd072f934514da34396d62 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -37,6 +37,7 @@ import PrometheusGraph from './monitoring/prometheus_graph'; // TODO: Maybe Make
 import Issue from './issue';
 
 import BindInOut from './behaviors/bind_in_out';
+import GroupName from './group_name';
 import GroupsList from './groups_list';
 import ProjectsList from './projects_list';
 import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
@@ -342,6 +343,9 @@ const UserCallout = require('./user_callout');
           shortcut_handler = new ShortcutsDashboardNavigation();
           new UserCallout();
           break;
+        case 'groups':
+          new GroupName();
+          break;
         case 'profiles':
           new NotificationsForm();
           new NotificationsDropdown();
@@ -349,6 +353,7 @@ const UserCallout = require('./user_callout');
         case 'projects':
           new Project();
           new ProjectAvatar();
+          new GroupName();
           switch (path[1]) {
             case 'compare':
               new CompareAutocomplete();
diff --git a/app/assets/javascripts/group_name.js b/app/assets/javascripts/group_name.js
new file mode 100644
index 0000000000000000000000000000000000000000..6a028f299b16230d0374ed5c45542211e8e32a6a
--- /dev/null
+++ b/app/assets/javascripts/group_name.js
@@ -0,0 +1,40 @@
+const GROUP_LIMIT = 2;
+
+export default class GroupName {
+  constructor() {
+    this.titleContainer = document.querySelector('.title');
+    this.groups = document.querySelectorAll('.group-path');
+    this.groupTitle = document.querySelector('.group-title');
+    this.toggle = null;
+    this.isHidden = false;
+    this.init();
+  }
+
+  init() {
+    if (this.groups.length > GROUP_LIMIT) {
+      this.groups[this.groups.length - 1].classList.remove('hidable');
+      this.addToggle();
+    }
+    this.render();
+  }
+
+  addToggle() {
+    const header = document.querySelector('.header-content');
+    this.toggle = document.createElement('button');
+    this.toggle.className = 'text-expander group-name-toggle';
+    this.toggle.setAttribute('aria-label', 'Toggle full path');
+    this.toggle.innerHTML = '...';
+    this.toggle.addEventListener('click', this.toggleGroups.bind(this));
+    header.insertBefore(this.toggle, this.titleContainer);
+    this.toggleGroups();
+  }
+
+  toggleGroups() {
+    this.isHidden = !this.isHidden;
+    this.groupTitle.classList.toggle('is-hidden');
+  }
+
+  render() {
+    this.titleContainer.classList.remove('initializing');
+  }
+}
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index 5d1aba4e529a986e619efa9598d628b81327c4bf..6660a0222607bbce625ccc8ed27ad58287775aee 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -164,11 +164,25 @@ header {
       }
     }
 
+    .group-name-toggle {
+      margin: 0 5px;
+      vertical-align: sub;
+    }
+
+    .group-title {
+      &.is-hidden {
+        .hidable:not(:last-of-type) {
+          display: none;
+        }
+      }
+    }
+
     .title {
       position: relative;
       padding-right: 20px;
       margin: 0;
       font-size: 18px;
+      max-width: 385px;
       display: inline-block;
       line-height: $header-height;
       font-weight: normal;
@@ -178,6 +192,14 @@ header {
       vertical-align: top;
       white-space: nowrap;
 
+      &.initializing {
+        display: none;
+      }
+
+      @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
+        max-width: 300px;
+      }
+
       @media (max-width: $screen-xs-max) {
         max-width: 190px;
       }
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 926c9703628158e1027666936133faa1da3469f3..a6014088e929f2dbf76f0d03aa519b5e04deedbc 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -12,17 +12,18 @@ module GroupsHelper
   end
 
   def group_title(group, name = nil, url = nil)
+    @has_group_title = true
     full_title = ''
 
     group.ancestors.each do |parent|
-      full_title += link_to(simple_sanitize(parent.name), group_path(parent))
-      full_title += ' / '.html_safe
+      full_title += link_to(simple_sanitize(parent.name), group_path(parent), class: 'group-path hidable')
+      full_title += '<span class="hidable"> / </span>'.html_safe
     end
 
-    full_title += link_to(simple_sanitize(group.name), group_path(group))
-    full_title += ' &middot; '.html_safe + link_to(simple_sanitize(name), url) if name
+    full_title += link_to(simple_sanitize(group.name), group_path(group), class: 'group-path')
+    full_title += ' &middot; '.html_safe + link_to(simple_sanitize(name), url, class: 'group-path') if name
 
-    content_tag :span do
+    content_tag :span, class: 'group-title' do
       full_title.html_safe
     end
   end
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 6f4f2dbea3a0d7022a3edfdf6b89b06ef4a572b4..5fde5c2613e3c5da3b6e1acba6391c830d12671d 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -67,7 +67,7 @@
         = link_to root_path, class: 'home', title: 'Dashboard', id: 'logo' do
           = brand_header_logo
 
-      %h1.title= title
+      %h1.title{ class: ('initializing' if @has_group_title) }= title
 
       = yield :header_content
 
diff --git a/changelogs/unreleased/28187-project-name-cut-off-with-nested-groups.yml b/changelogs/unreleased/28187-project-name-cut-off-with-nested-groups.yml
new file mode 100644
index 0000000000000000000000000000000000000000..feca38ff083ad461b5c8d4e53283a99c832f161d
--- /dev/null
+++ b/changelogs/unreleased/28187-project-name-cut-off-with-nested-groups.yml
@@ -0,0 +1,4 @@
+---
+title: Use toggle button to expand / collapse mulit-nested groups
+merge_request: 9501
+author:
diff --git a/spec/features/groups/group_name_toggle.rb b/spec/features/groups/group_name_toggle.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ada4ac66e04e51f92cf9bf9d523f55b474fc358b
--- /dev/null
+++ b/spec/features/groups/group_name_toggle.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+feature 'Group name toggle', js: true do
+  let(:group) { create(:group) }
+  let(:nested_group_1) { create(:group, parent: group) }
+  let(:nested_group_2) { create(:group, parent: nested_group_1) }
+  let(:nested_group_3) { create(:group, parent: nested_group_2) }
+
+  before do
+    login_as :user
+  end
+
+  it 'is not present for less than 3 groups' do
+    visit group_path(group)
+    expect(page).not_to have_css('.group-name-toggle')
+
+    visit group_path(nested_group_1)
+    expect(page).not_to have_css('.group-name-toggle')
+  end
+
+  it 'is present for nested group of 3 or more in the namespace' do
+    visit group_path(nested_group_2)
+    expect(page).to have_css('.group-name-toggle')
+
+    visit group_path(nested_group_3)
+    expect(page).to have_css('.group-name-toggle')
+  end
+
+  context 'for group with at least 3 groups' do
+    before do
+      visit group_path(nested_group_2)
+    end
+
+    it 'should show the full group namespace when toggled' do
+      expect(page).not_to have_content(group.name)
+      expect(page).to have_css('.group-path.hidable', visible: false)
+
+      click_button '...'
+
+      expect(page).to have_content(group.name)
+      expect(page).to have_css('.group-path.hidable', visible: true)
+    end
+  end
+end