diff --git a/app/assets/javascripts/project_new.js b/app/assets/javascripts/project_new.js
index 04b381fe0e00f29555a2e42f9b9f5234a94125fa..c0f757269cbe8f0e33d862236ce14f472c0b42b3 100644
--- a/app/assets/javascripts/project_new.js
+++ b/app/assets/javascripts/project_new.js
@@ -1,11 +1,17 @@
 /* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-unused-vars, one-var, no-underscore-dangle, prefer-template, no-else-return, prefer-arrow-callback, max-len */
 
+function highlightChanges($elm) {
+  $elm.addClass('highlight-changes');
+  setTimeout(() => $elm.removeClass('highlight-changes'), 10);
+}
+
 (function() {
   this.ProjectNew = (function() {
     function ProjectNew() {
       this.toggleSettings = this.toggleSettings.bind(this);
       this.$selects = $('.features select');
       this.$repoSelects = this.$selects.filter('.js-repo-select');
+      this.$projectSelects = this.$selects.not('.js-repo-select');
 
       $('.project-edit-container').on('ajax:before', (function(_this) {
         return function() {
@@ -26,6 +32,42 @@
       if (!visibilityContainer) return;
       const visibilitySelect = new gl.VisibilitySelect(visibilityContainer);
       visibilitySelect.init();
+
+      const $visibilitySelect = $(visibilityContainer).find('select');
+      let projectVisibility = $visibilitySelect.val();
+      const PROJECT_VISIBILITY_PRIVATE = '0';
+
+      $visibilitySelect.on('change', () => {
+        const newProjectVisibility = $visibilitySelect.val();
+
+        if (projectVisibility !== newProjectVisibility) {
+          this.$projectSelects.each((idx, select) => {
+            const $select = $(select);
+            const $options = $select.find('option');
+            const values = $.map($options, e => e.value);
+
+            // if switched to "private", limit visibility options
+            if (newProjectVisibility === PROJECT_VISIBILITY_PRIVATE) {
+              if ($select.val() !== values[0] && $select.val() !== values[1]) {
+                $select.val(values[1]).trigger('change');
+                highlightChanges($select);
+              }
+              $options.slice(2).disable();
+            }
+
+            // if switched from "private", increase visibility for non-disabled options
+            if (projectVisibility === PROJECT_VISIBILITY_PRIVATE) {
+              $options.enable();
+              if ($select.val() !== values[0] && $select.val() !== values[values.length - 1]) {
+                $select.val(values[values.length - 1]).trigger('change');
+                highlightChanges($select);
+              }
+            }
+          });
+
+          projectVisibility = newProjectVisibility;
+        }
+      });
     };
 
     ProjectNew.prototype.toggleSettings = function() {
@@ -56,8 +98,10 @@
 
     ProjectNew.prototype.toggleRepoVisibility = function () {
       var $repoAccessLevel = $('.js-repo-access-level select');
+      var $lfsEnabledOption = $('.js-lfs-enabled select');
       var containerRegistry = document.querySelectorAll('.js-container-registry')[0];
       var containerRegistryCheckbox = document.getElementById('project_container_registry_enabled');
+      var prevSelectedVal = parseInt($repoAccessLevel.val(), 10);
 
       this.$repoSelects.find("option[value='" + $repoAccessLevel.val() + "']")
         .nextAll()
@@ -71,29 +115,40 @@
             var $this = $(this);
             var repoSelectVal = parseInt($this.val(), 10);
 
-            $this.find('option').show();
+            $this.find('option').enable();
 
-            if (selectedVal < repoSelectVal) {
-              $this.val(selectedVal);
+            if (selectedVal < repoSelectVal || repoSelectVal === prevSelectedVal) {
+              $this.val(selectedVal).trigger('change');
+              highlightChanges($this);
             }
 
-            $this.find("option[value='" + selectedVal + "']").nextAll().hide();
+            $this.find("option[value='" + selectedVal + "']").nextAll().disable();
           });
 
           if (selectedVal) {
             this.$repoSelects.removeClass('disabled');
 
+            if ($lfsEnabledOption.length) {
+              $lfsEnabledOption.removeClass('disabled');
+              highlightChanges($lfsEnabledOption);
+            }
             if (containerRegistry) {
               containerRegistry.style.display = '';
             }
           } else {
             this.$repoSelects.addClass('disabled');
 
+            if ($lfsEnabledOption.length) {
+              $lfsEnabledOption.val('false').addClass('disabled');
+              highlightChanges($lfsEnabledOption);
+            }
             if (containerRegistry) {
               containerRegistry.style.display = 'none';
               containerRegistryCheckbox.checked = false;
             }
           }
+
+          prevSelectedVal = selectedVal;
         }.bind(this));
     };
 
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index b3a86b92d935ded4bbba30187ef741fb05c3172e..4114a050d9a3509fe8ea0dec71bdce05c1271a3a 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -187,6 +187,7 @@ $divergence-graph-bar-bg: #ccc;
 $divergence-graph-separator-bg: #ccc;
 $general-hover-transition-duration: 100ms;
 $general-hover-transition-curve: linear;
+$highlight-changes-color: rgb(235, 255, 232);
 
 
 /*
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 4719bf826dc205bd4478e854a637cc942e797191..a2f781a6a6eada7a965ce64bb2249a0a5a2720dd 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -29,6 +29,20 @@
     & > .form-group {
       padding-left: 0;
     }
+
+    select option[disabled] {
+      display: none;
+    }
+  }
+
+  select {
+    background: transparent;
+    transition: background 2s ease-out;
+
+    &.highlight-changes {
+      background: $highlight-changes-color;
+      transition: none;
+    }
   }
 
   .help-block {
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 7b0584c42a2a3cfef2c5b808022a2d16b6277c9c..f74e61c9481f7a625fc7c78f94e85c187fca4fb5 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -138,11 +138,15 @@ module ProjectsHelper
 
     if @project.private?
       level = @project.project_feature.send(field)
-      options.delete('Everyone with access')
-      highest_available_option = options.values.max if level == ProjectFeature::ENABLED
+      disabled_option = ProjectFeature::ENABLED
+      highest_available_option = ProjectFeature::PRIVATE if level == disabled_option
     end
 
-    options = options_for_select(options, selected: highest_available_option || @project.project_feature.public_send(field))
+    options = options_for_select(
+      options,
+      selected: highest_available_option || @project.project_feature.public_send(field),
+      disabled: disabled_option
+    )
 
     content_tag(
       :select,
diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb
index b4aaf498068414349863bd77f29ca40666e77711..50757b01538ed49a03ee22861286aa6cb9454ba3 100644
--- a/app/helpers/visibility_level_helper.rb
+++ b/app/helpers/visibility_level_helper.rb
@@ -31,9 +31,9 @@ module VisibilityLevelHelper
     when Gitlab::VisibilityLevel::PRIVATE
       "Project access must be granted explicitly to each user."
     when Gitlab::VisibilityLevel::INTERNAL
-      "The project can be cloned by any logged in user."
+      "The project can be accessed by any logged in user."
     when Gitlab::VisibilityLevel::PUBLIC
-      "The project can be cloned without any authentication."
+      "The project can be accessed without any authentication."
     end
   end
 
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index f5549d7f4cde80efad4a32e3b22882d72e312b5f..c3dab68cea57c09254a0627bd34b6522db0ce712 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -42,7 +42,7 @@
               .col-md-9
                 .label-light
                   = label_tag :project_visibility, 'Project Visibility', class: 'label-light', for: :project_visibility_level
-                  = link_to "(?)", help_page_path("public_access/public_access")
+                  = link_to icon('question-circle'), help_page_path("public_access/public_access")
                 %span.help-block
               .col-md-3.visibility-select-container
                 = render('projects/visibility_select', model_method: :visibility_level, form: f, selected_level: @project.visibility_level)
@@ -92,14 +92,14 @@
           .form-group
             = render 'shared/allow_request_access', form: f
           - if Gitlab.config.lfs.enabled && current_user.admin?
-            .row
+            .row.js-lfs-enabled
               .col-md-9
                 = f.label :lfs_enabled, 'LFS', class: 'label-light'
                 %span.help-block
                   Git Large File Storage
                   = link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
               .col-md-3
-                = f.select :lfs_enabled, [%w(Enabled true), %w(Disabled false)], {}, selected: @project.lfs_enabled?, class: 'pull-right form-control', data: { field: 'lfs_enabled' }
+                = f.select :lfs_enabled, [%w(Enabled true), %w(Disabled false)], {}, selected: @project.lfs_enabled?, class: 'pull-right form-control project-repo-select', data: { field: 'lfs_enabled' }
 
 
         - if Gitlab.config.registry.enabled
diff --git a/changelogs/unreleased/24032-when-changing-project-visibility-setting-change-other-dropdowns-automatically.yml b/changelogs/unreleased/24032-when-changing-project-visibility-setting-change-other-dropdowns-automatically.yml
new file mode 100644
index 0000000000000000000000000000000000000000..dbd8a538d517f709ab762fae07717b945bf66af0
--- /dev/null
+++ b/changelogs/unreleased/24032-when-changing-project-visibility-setting-change-other-dropdowns-automatically.yml
@@ -0,0 +1,4 @@
+---
+title: Automatically adjust project settings to match changes in project visibility
+merge_request: 11831
+author:
diff --git a/spec/features/projects/settings/visibility_settings_spec.rb b/spec/features/projects/settings/visibility_settings_spec.rb
index cef315ac9cdf3dd0752dbd239d454410d8a885f6..fac4506bdf65cb3fd589706c52af09f8e409e573 100644
--- a/spec/features/projects/settings/visibility_settings_spec.rb
+++ b/spec/features/projects/settings/visibility_settings_spec.rb
@@ -14,7 +14,7 @@ feature 'Visibility settings', feature: true, js: true do
       visibility_select_container = find('.js-visibility-select')
 
       expect(visibility_select_container.find('.visibility-select').value).to eq project.visibility_level.to_s
-      expect(visibility_select_container).to have_content 'The project can be cloned without any authentication.'
+      expect(visibility_select_container).to have_content 'The project can be accessed without any authentication.'
     end
 
     scenario 'project visibility description updates on change' do
@@ -41,7 +41,7 @@ feature 'Visibility settings', feature: true, js: true do
 
       expect(visibility_select_container).not_to have_select '.visibility-select'
       expect(visibility_select_container).to have_content 'Public'
-      expect(visibility_select_container).to have_content 'The project can be cloned without any authentication.'
+      expect(visibility_select_container).to have_content 'The project can be accessed without any authentication.'
     end
   end
 end
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 54c5ba57bdf93795ea09e0e29f2470596a765032..a695621b87a2499a58aa40d169925668aa34c685 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -257,7 +257,7 @@ describe ProjectsHelper do
         result = helper.project_feature_access_select(:issues_access_level)
         expect(result).to include("Disabled")
         expect(result).to include("Only team members")
-        expect(result).not_to include("Everyone with access")
+        expect(result).to have_selector('option[disabled]', text: "Everyone with access")
       end
     end
 
@@ -272,7 +272,7 @@ describe ProjectsHelper do
 
         expect(result).to include("Disabled")
         expect(result).to include("Only team members")
-        expect(result).not_to include("Everyone with access")
+        expect(result).to have_selector('option[disabled]', text: "Everyone with access")
         expect(result).to have_selector('option[selected]', text: "Only team members")
       end
     end
diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb
index 8942b00b128219918015fb2a6ca36b0e44ff9f0c..ad19cf9263d6b07cd6a7b33bc13f22d770788695 100644
--- a/spec/helpers/visibility_level_helper_spec.rb
+++ b/spec/helpers/visibility_level_helper_spec.rb
@@ -37,7 +37,7 @@ describe VisibilityLevelHelper do
 
     it "describes public projects" do
       expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC))
-            .to eq "The project can be cloned without any authentication."
+            .to eq "The project can be accessed without any authentication."
     end
   end