diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs
index 24398c2235..4f5a44e61d 100644
--- a/osu.Game.Rulesets.Osu/Objects/Slider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs
@@ -170,6 +170,7 @@ namespace osu.Game.Rulesets.Osu.Objects
                         StackHeight = StackHeight,
                         Scale = Scale,
                         ComboColour = ComboColour,
+                        Samples = new SampleInfoList(RepeatSamples[repeat])
                     });
                 }
             }
diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs
index 66af72dad9..639befef74 100644
--- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs
+++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs
@@ -69,6 +69,7 @@ namespace osu.Game.Tests.Visual
             testSorting();
 
             testRemoveAll();
+            testEmptyTraversal();
         }
 
         private void ensureRandomFetchSuccess() =>
@@ -103,6 +104,8 @@ namespace osu.Game.Tests.Visual
             AddAssert($"{count} {(diff ? "diffs" : "sets")} visible", () =>
                 carousel.Items.Count(s => (diff ? s.Item is CarouselBeatmap : s.Item is CarouselBeatmapSet) && s.Item.Visible) == count);
 
+        private void checkNoSelection() => AddAssert("Selection is null", () => currentSelection == null);
+
         private void nextRandom() =>
             AddStep("select random next", () =>
             {
@@ -274,9 +277,23 @@ namespace osu.Game.Tests.Visual
                 return false;
             }, "Remove all");
 
-            AddAssert("Selection is null", () => currentSelection == null);
+            checkNoSelection();
         }
 
+        private void testEmptyTraversal()
+        {
+            advanceSelection(direction: 1, diff: false);
+            checkNoSelection();
+
+            advanceSelection(direction: 1, diff: true);
+            checkNoSelection();
+
+            advanceSelection(direction: -1, diff: false);
+            checkNoSelection();
+
+            advanceSelection(direction: -1, diff: true);
+            checkNoSelection();
+        }
 
         private BeatmapSetInfo createTestBeatmapSet(int i)
         {
diff --git a/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs b/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs
index 79d3d7d4ba..b93c2d812f 100644
--- a/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs
+++ b/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs
@@ -3,19 +3,17 @@
 
 using System.Collections.Generic;
 using System.Linq;
-using NUnit.Framework;
 using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
 using osu.Framework.MathUtils;
 using osu.Game.Overlays;
 using osu.Game.Overlays.Notifications;
 
 namespace osu.Game.Tests.Visual
 {
-    [TestFixture]
     public class TestCaseNotificationOverlay : OsuTestCase
     {
         private readonly NotificationOverlay manager;
+        private readonly List<ProgressNotification> progressingNotifications = new List<ProgressNotification>();
 
         public TestCaseNotificationOverlay()
         {
@@ -24,15 +22,14 @@ namespace osu.Game.Tests.Visual
             Content.Add(manager = new NotificationOverlay
             {
                 Anchor = Anchor.TopRight,
-                Origin = Anchor.TopRight,
+                Origin = Anchor.TopRight
             });
 
-            AddToggleStep(@"show", state => manager.State = state ? Visibility.Visible : Visibility.Hidden);
-
-            AddStep(@"simple #1", sendNotification1);
-            AddStep(@"simple #2", sendNotification2);
-            AddStep(@"progress #1", sendProgress1);
-            AddStep(@"progress #2", sendProgress2);
+            AddStep(@"toggle", manager.ToggleVisibility);
+            AddStep(@"simple #1", sendHelloNotification);
+            AddStep(@"simple #2", sendAmazingNotification);
+            AddStep(@"progress #1", sendUploadProgress);
+            AddStep(@"progress #2", sendDownloadProgress);
             AddStep(@"barrage", () => sendBarrage());
         }
 
@@ -41,16 +38,16 @@ namespace osu.Game.Tests.Visual
             switch (RNG.Next(0, 4))
             {
                 case 0:
-                    sendNotification1();
+                    sendHelloNotification();
                     break;
                 case 1:
-                    sendNotification2();
+                    sendAmazingNotification();
                     break;
                 case 2:
-                    sendProgress1();
+                    sendUploadProgress();
                     break;
                 case 3:
-                    sendProgress2();
+                    sendDownloadProgress();
                     break;
             }
 
@@ -80,7 +77,7 @@ namespace osu.Game.Tests.Visual
             }
         }
 
-        private void sendProgress2()
+        private void sendDownloadProgress()
         {
             var n = new ProgressNotification
             {
@@ -91,9 +88,7 @@ namespace osu.Game.Tests.Visual
             progressingNotifications.Add(n);
         }
 
-        private readonly List<ProgressNotification> progressingNotifications = new List<ProgressNotification>();
-
-        private void sendProgress1()
+        private void sendUploadProgress()
         {
             var n = new ProgressNotification
             {
@@ -104,12 +99,12 @@ namespace osu.Game.Tests.Visual
             progressingNotifications.Add(n);
         }
 
-        private void sendNotification2()
+        private void sendAmazingNotification()
         {
             manager.Post(new SimpleNotification { Text = @"You are amazing" });
         }
 
-        private void sendNotification1()
+        private void sendHelloNotification()
         {
             manager.Post(new SimpleNotification { Text = @"Welcome to osu!. Enjoy your stay!" });
         }
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index 4745733bd9..67f6e6f4e2 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -37,7 +37,7 @@ namespace osu.Game
 
         private MusicController musicController;
 
-        private NotificationOverlay notificationOverlay;
+        private NotificationOverlay notifications;
 
         private DialogOverlay dialogOverlay;
 
@@ -136,7 +136,7 @@ namespace osu.Game
 
             if (s.Beatmap == null)
             {
-                notificationOverlay.Post(new SimpleNotification
+                notifications.Post(new SimpleNotification
                 {
                     Text = @"Tried to load a score for a beatmap we don't have!",
                     Icon = FontAwesome.fa_life_saver,
@@ -154,7 +154,7 @@ namespace osu.Game
             base.LoadComplete();
 
             // hook up notifications to components.
-            BeatmapManager.PostNotification = n => notificationOverlay?.Post(n);
+            BeatmapManager.PostNotification = n => notifications?.Post(n);
             BeatmapManager.GetStableStorage = GetStorageForStableInstall;
 
             AddRange(new Drawable[]
@@ -207,8 +207,9 @@ namespace osu.Game
                 Origin = Anchor.TopRight,
             }, overlayContent.Add);
 
-            loadComponentSingleFile(notificationOverlay = new NotificationOverlay
+            loadComponentSingleFile(notifications = new NotificationOverlay
             {
+                GetToolbarHeight = () => ToolbarOffset,
                 Depth = -4,
                 Anchor = Anchor.TopRight,
                 Origin = Anchor.TopRight,
@@ -223,7 +224,7 @@ namespace osu.Game
             {
                 if (entry.Level < LogLevel.Important) return;
 
-                notificationOverlay.Post(new SimpleNotification
+                notifications.Post(new SimpleNotification
                 {
                     Text = $@"{entry.Level}: {entry.Message}"
                 });
@@ -236,7 +237,7 @@ namespace osu.Game
             dependencies.Cache(userProfile);
             dependencies.Cache(musicController);
             dependencies.Cache(beatmapSetOverlay);
-            dependencies.Cache(notificationOverlay);
+            dependencies.Cache(notifications);
             dependencies.Cache(dialogOverlay);
 
             // ensure only one of these overlays are open at once.
@@ -271,19 +272,21 @@ namespace osu.Game
                 };
             }
 
-            settings.StateChanged += delegate
+            Action<Visibility> stateChanged = delegate
             {
-                switch (settings.State)
-                {
-                    case Visibility.Hidden:
-                        intro.MoveToX(0, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
-                        break;
-                    case Visibility.Visible:
-                        intro.MoveToX(SettingsOverlay.SIDEBAR_WIDTH / 2, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
-                        break;
-                }
+                float offset = 0;
+
+                if (settings.State == Visibility.Visible)
+                    offset += ToolbarButton.WIDTH / 2;
+                if (notifications.State == Visibility.Visible)
+                    offset -= ToolbarButton.WIDTH / 2;
+
+                intro.MoveToX(offset, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
             };
 
+            settings.StateChanged += stateChanged;
+            notifications.StateChanged += stateChanged;
+
             Cursor.State = Visibility.Hidden;
         }
 
@@ -351,7 +354,7 @@ namespace osu.Game
             direct.State = Visibility.Hidden;
             social.State = Visibility.Hidden;
             userProfile.State = Visibility.Hidden;
-            notificationOverlay.State = Visibility.Hidden;
+            notifications.State = Visibility.Hidden;
         }
 
         private void screenChanged(Screen newScreen)
diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs
index 260214a14f..a4b5486596 100644
--- a/osu.Game/Overlays/NotificationOverlay.cs
+++ b/osu.Game/Overlays/NotificationOverlay.cs
@@ -10,6 +10,7 @@ using osu.Game.Overlays.Notifications;
 using OpenTK.Graphics;
 using osu.Framework.Graphics.Shapes;
 using osu.Game.Graphics.Containers;
+using System;
 
 namespace osu.Game.Overlays
 {
@@ -19,9 +20,13 @@ namespace osu.Game.Overlays
 
         public const float TRANSITION_LENGTH = 600;
 
-        private ScrollContainer scrollContainer;
         private FlowContainer<NotificationSection> sections;
 
+        /// <summary>
+        /// Provide a source for the toolbar height.
+        /// </summary>
+        public Func<float> GetToolbarHeight;
+
         [BackgroundDependencyLoader]
         private void load()
         {
@@ -36,12 +41,12 @@ namespace osu.Game.Overlays
                 {
                     RelativeSizeAxes = Axes.Both,
                     Colour = Color4.Black,
-                    Alpha = 0.6f,
+                    Alpha = 0.6f
                 },
-                scrollContainer = new OsuScrollContainer
+                new OsuScrollContainer
                 {
+                    Masking = true,
                     RelativeSizeAxes = Axes.Both,
-                    Margin = new MarginPadding { Top = Toolbar.Toolbar.HEIGHT },
                     Children = new[]
                     {
                         sections = new FillFlowContainer<NotificationSection>
@@ -55,14 +60,14 @@ namespace osu.Game.Overlays
                                 {
                                     Title = @"Notifications",
                                     ClearText = @"Clear All",
-                                    AcceptTypes = new[] { typeof(SimpleNotification) },
+                                    AcceptTypes = new[] { typeof(SimpleNotification) }
                                 },
                                 new NotificationSection
                                 {
                                     Title = @"Running Tasks",
                                     ClearText = @"Cancel All",
-                                    AcceptTypes = new[] { typeof(ProgressNotification) },
-                                },
+                                    AcceptTypes = new[] { typeof(ProgressNotification) }
+                                }
                             }
                         }
                     }
@@ -103,14 +108,8 @@ namespace osu.Game.Overlays
         {
             base.PopIn();
 
-            scrollContainer.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint);
             this.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint);
-            this.FadeTo(1, TRANSITION_LENGTH / 2);
-        }
-
-        private void markAllRead()
-        {
-            sections.Children.ForEach(s => s.MarkAllRead());
+            this.FadeTo(1, TRANSITION_LENGTH, Easing.OutQuint);
         }
 
         protected override void PopOut()
@@ -120,7 +119,19 @@ namespace osu.Game.Overlays
             markAllRead();
 
             this.MoveToX(width, TRANSITION_LENGTH, Easing.OutQuint);
-            this.FadeTo(0, TRANSITION_LENGTH / 2);
+            this.FadeTo(0, TRANSITION_LENGTH, Easing.OutQuint);
+        }
+
+        private void markAllRead()
+        {
+            sections.Children.ForEach(s => s.MarkAllRead());
+        }
+
+        protected override void UpdateAfterChildren()
+        {
+            base.UpdateAfterChildren();
+
+            Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 };
         }
     }
 }
diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs
index 798fa00032..a80f6d4da8 100644
--- a/osu.Game/Overlays/SettingsOverlay.cs
+++ b/osu.Game/Overlays/SettingsOverlay.cs
@@ -24,7 +24,7 @@ namespace osu.Game.Overlays
 
         public const float TRANSITION_LENGTH = 600;
 
-        public const float SIDEBAR_WIDTH = Sidebar.DEFAULT_WIDTH;
+        private const float sidebar_width = Sidebar.DEFAULT_WIDTH;
 
         protected const float WIDTH = 400;
 
@@ -102,7 +102,7 @@ namespace osu.Game.Overlays
 
             if (showSidebar)
             {
-                AddInternal(Sidebar = new Sidebar { Width = SIDEBAR_WIDTH });
+                AddInternal(Sidebar = new Sidebar { Width = sidebar_width });
 
                 SectionsContainer.SelectedSection.ValueChanged += section =>
                 {
@@ -167,7 +167,7 @@ namespace osu.Game.Overlays
 
             ContentContainer.MoveToX(-WIDTH, TRANSITION_LENGTH, Easing.OutQuint);
 
-            Sidebar?.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, Easing.OutQuint);
+            Sidebar?.MoveToX(-sidebar_width, TRANSITION_LENGTH, Easing.OutQuint);
             this.FadeTo(0, TRANSITION_LENGTH, Easing.OutQuint);
 
             searchTextBox.HoldFocus = false;
diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs
index ff1dd95eac..be176c1459 100644
--- a/osu.Game/Screens/Select/BeatmapCarousel.cs
+++ b/osu.Game/Screens/Select/BeatmapCarousel.cs
@@ -181,6 +181,9 @@ namespace osu.Game.Screens.Select
         /// <param name="skipDifficulties">Whether to skip individual difficulties and only increment over full groups.</param>
         public void SelectNext(int direction = 1, bool skipDifficulties = true)
         {
+            if (!Items.Any())
+                return;
+
             int originalIndex = Items.IndexOf(selectedBeatmap?.Drawables.First());
             int currentIndex = originalIndex;