diff --git a/app/assets/javascripts/environments/components/environment_stop.vue b/app/assets/javascripts/environments/components/environment_stop.vue
index ba81cab225626e967f00bcd8ff3f073a4d646ddb..d608eebd1ae6b029ec413a9fd1cfcda74d7149c8 100644
--- a/app/assets/javascripts/environments/components/environment_stop.vue
+++ b/app/assets/javascripts/environments/components/environment_stop.vue
@@ -39,7 +39,8 @@ export default {
     },
   },
   i18n: {
-    title: s__('Environments|Stop environment'),
+    stopTitle: s__('Environments|Stop environment'),
+    stoppingTitle: s__('Environments|Stopping environment'),
   },
   data() {
     return {
@@ -47,6 +48,14 @@ export default {
       isEnvironmentStopping: false,
     };
   },
+  computed: {
+    isLoadingState() {
+      return this.environment.state === 'stopping' || this.isEnvironmentStopping || this.isLoading;
+    },
+    title() {
+      return this.isLoadingState ? this.$options.i18n.stoppingTitle : this.$options.i18n.stopTitle;
+    },
+  },
   mounted() {
     eventHub.$on('stopEnvironment', this.onStopEnvironment);
   },
@@ -75,16 +84,23 @@ export default {
 };
 </script>
 <template>
-  <gl-button
+  <div
     v-gl-tooltip="{ id: $options.stopEnvironmentTooltipId }"
-    v-gl-modal-directive="'stop-environment-modal'"
-    :loading="isLoading || isEnvironmentStopping"
-    :title="$options.i18n.title"
-    :aria-label="$options.i18n.title"
-    size="small"
-    icon="stop"
-    category="secondary"
-    variant="danger"
-    @click="onClick"
-  />
+    :title="title"
+    :tabindex="isLoadingState ? 0 : null"
+    class="gl-relative -gl-ml-[1px]"
+  >
+    <gl-button
+      v-gl-modal-directive="'stop-environment-modal'"
+      :loading="isLoadingState"
+      :aria-label="title"
+      :class="{ 'gl-pointer-events-none': isLoadingState }"
+      class="!gl-rounded-none"
+      size="small"
+      icon="stop"
+      category="secondary"
+      variant="danger"
+      @click="onClick"
+    />
+  </div>
 </template>
diff --git a/app/assets/javascripts/environments/components/new_environment_item.vue b/app/assets/javascripts/environments/components/new_environment_item.vue
index 12b2aec47b51565a4ab8ceefdc02f7c11dcaa935..72946320ada912097aef59c2ad08ecf446ff6737 100644
--- a/app/assets/javascripts/environments/components/new_environment_item.vue
+++ b/app/assets/javascripts/environments/components/new_environment_item.vue
@@ -110,6 +110,9 @@ export default {
         ...action,
       }));
     },
+    isEnvironmentStopping() {
+      return this.environment?.state === 'stopping';
+    },
     canStop() {
       return this.environment?.canStop;
     },
@@ -233,7 +236,7 @@ export default {
           />
 
           <stop-component
-            v-if="canStop"
+            v-if="canStop || isEnvironmentStopping"
             :environment="environment"
             data-track-action="click_button"
             data-track-label="environment_stop"
diff --git a/ee/spec/features/projects/environments/environments_spec.rb b/ee/spec/features/projects/environments/environments_spec.rb
index 03485a4ff1b3ecdc67f45ad570fbf4f76366ea9f..b76bfc3868d3cdf00229a0916f3c27ad34e796bd 100644
--- a/ee/spec/features/projects/environments/environments_spec.rb
+++ b/ee/spec/features/projects/environments/environments_spec.rb
@@ -69,7 +69,7 @@ def actions_button_selector
       end
 
       it 'shows a stop button' do
-        stop_button_selector = %q(button[title="Stop environment"])
+        stop_button_selector = %q(button[aria-label="Stop environment"])
 
         expect(page).to have_selector(stop_button_selector)
       end
@@ -166,7 +166,7 @@ def actions_button_selector
       end
 
       it 'does not show a stop button' do
-        stop_button_selector = %q(button[title="Stop environment"])
+        stop_button_selector = %q(button[aria-label="Stop environment"])
 
         expect(page).not_to have_selector(stop_button_selector)
       end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 3d52109a16d3f3a307f373dd7c6df0cf51bdaf65..c3b6e65cc358a296498aac32b383d058a4f1a54d 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -22805,6 +22805,9 @@ msgstr ""
 msgid "Environments|Stop unused environments"
 msgstr ""
 
+msgid "Environments|Stopping environment"
+msgstr ""
+
 msgid "Environments|Synced"
 msgstr ""
 
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index 0e44ab71ce15cdac554c7f07f081943271060a06..c928a570d1dd37ecca1dd4246ccea161338844d6 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -23,7 +23,7 @@ def action_link_selector
   end
 
   def stop_button_selector
-    'button[title="Stop environment"]'
+    'button[aria-label="Stop environment"]'
   end
 
   def upcoming_deployment_content_selector
diff --git a/spec/frontend/environments/environment_stop_spec.js b/spec/frontend/environments/environment_stop_spec.js
index 3e27b8822e197306aac8a32d6749e3154f69e655..186126332a815e3ae5e3555000ece93b5f2ea26c 100644
--- a/spec/frontend/environments/environment_stop_spec.js
+++ b/spec/frontend/environments/environment_stop_spec.js
@@ -7,6 +7,7 @@ import isEnvironmentStoppingQuery from '~/environments/graphql/queries/is_enviro
 import StopComponent from '~/environments/components/environment_stop.vue';
 import eventHub from '~/environments/event_hub';
 import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
 import { resolvedEnvironment } from './graphql/mock_data';
 
 describe('Stop Component', () => {
@@ -24,7 +25,7 @@ describe('Stop Component', () => {
 
   const findButton = () => wrapper.findComponent(GlButton);
 
-  describe('eventHub', () => {
+  describe('default', () => {
     beforeEach(() => {
       createWrapper();
     });
@@ -33,6 +34,12 @@ describe('Stop Component', () => {
       expect(findButton().exists()).toBe(true);
       expect(wrapper.attributes('title')).toEqual('Stop environment');
     });
+  });
+
+  describe('eventHub', () => {
+    beforeEach(() => {
+      createWrapper();
+    });
 
     it('emits requestStopEnvironment in the event hub when button is clicked', () => {
       jest.spyOn(eventHub, '$emit');
@@ -44,37 +51,72 @@ describe('Stop Component', () => {
   describe('graphql', () => {
     Vue.use(VueApollo);
     let mockApollo;
+    const resolvers = {
+      Query: {
+        isEnvironmentStopping: () => true,
+      },
+    };
 
-    beforeEach(() => {
-      mockApollo = createMockApollo();
-      mockApollo.clients.defaultClient.writeQuery({
-        query: isEnvironmentStoppingQuery,
-        variables: { environment: resolvedEnvironment },
-        data: { isEnvironmentStopping: true },
-      });
-
+    const createWrapperWithApollo = () => {
       createWrapper(
         { graphql: true, environment: resolvedEnvironment },
         { apolloProvider: mockApollo },
       );
-    });
+    };
 
-    it('should render a button to stop the environment', () => {
-      expect(findButton().exists()).toBe(true);
-      expect(wrapper.attributes('title')).toEqual('Stop environment');
+    it('queries for environment stopping state', () => {
+      mockApollo = createMockApollo([], resolvers);
+      jest.spyOn(mockApollo.defaultClient, 'watchQuery');
+
+      createWrapperWithApollo();
+
+      expect(mockApollo.defaultClient.watchQuery).toHaveBeenCalledWith({
+        query: isEnvironmentStoppingQuery,
+        variables: { environment: resolvedEnvironment },
+      });
     });
 
     it('sets the environment to stop on click', () => {
+      mockApollo = createMockApollo();
       jest.spyOn(mockApollo.defaultClient, 'mutate');
+
+      createWrapperWithApollo();
+
       findButton().vm.$emit('click');
+
       expect(mockApollo.defaultClient.mutate).toHaveBeenCalledWith({
         mutation: setEnvironmentToStopMutation,
         variables: { environment: resolvedEnvironment },
       });
     });
 
-    it('should show a loading icon if the environment is currently stopping', () => {
-      expect(findButton().props('loading')).toBe(true);
+    describe('when the environment is currently stopping', () => {
+      beforeEach(async () => {
+        mockApollo = createMockApollo([], resolvers);
+
+        createWrapperWithApollo();
+        await waitForPromises();
+      });
+
+      it('should render a button with a loading icon and a correct title', () => {
+        const button = findButton();
+
+        expect(button.props('loading')).toBe(true);
+        expect(wrapper.attributes('title')).toBe('Stopping environment');
+      });
+    });
+  });
+
+  describe('when the environment is in stopping state', () => {
+    beforeEach(() => {
+      createWrapper({ environment: { ...resolvedEnvironment, state: 'stopping' } });
+    });
+
+    it('should render a button with a loading icon and a correct title', () => {
+      const button = findButton();
+
+      expect(button.props('loading')).toBe(true);
+      expect(wrapper.attributes('title')).toBe('Stopping environment');
     });
   });
 });
diff --git a/spec/frontend/environments/new_environment_item_spec.js b/spec/frontend/environments/new_environment_item_spec.js
index 8ad30e657c226e29aff9cee8b024ae1b14e2b489..fbc9d1aac65842f72f305bb966acb4cbdeb053cc 100644
--- a/spec/frontend/environments/new_environment_item_spec.js
+++ b/spec/frontend/environments/new_environment_item_spec.js
@@ -163,6 +163,15 @@ describe('~/environments/components/new_environment_item.vue', () => {
 
       expect(findStopComponent().exists()).toBe(false);
     });
+
+    it('shows a button to stop the environment if the environment is in stopping state', () => {
+      wrapper = createWrapper({
+        propsData: { environment: { ...resolvedEnvironment, state: 'stopping' } },
+        apolloProvider: createApolloProvider(),
+      });
+
+      expect(findStopComponent().exists()).toBe(true);
+    });
   });
 
   describe('rollback', () => {