Skip to content

Instantly share code, notes, and snippets.

@Felvesthe
Created April 8, 2025 18:22
Show Gist options
  • Save Felvesthe/8a13560ed3135ab1fbec2b06a18402da to your computer and use it in GitHub Desktop.
Save Felvesthe/8a13560ed3135ab1fbec2b06a18402da to your computer and use it in GitHub Desktop.
Custom CSS for Vivaldi Browser providing Arc Browser-like auto-hide functionality for vertical tabs.
/*
Custom CSS for Vivaldi Browser providing Arc Browser-like auto-hide functionality for vertical tabs.
Fully compatible with workspaces.
This customization was made and tested with the tab bar positioned on the left side of the screen,
but it should also work on the right side.
*/
:root {
--tabbar-transition: transform .2s ease-out, opacity .2s ease-out;
--scrollbar-width: 10px;
--scrollbar-border-color: #9fb0cb;
--tabbar-peek-width: 3px;
}
/*----- Scrollbar Styling -----*/
#tabs-tabbar-container:is(.left, .right) .tab-strip::-webkit-scrollbar {
padding: 0 2px !important;
width: var(--scrollbar-width) !important;
border: 1px solid var(--scrollbar-border-color) !important;
border-radius: 8px !important;
}
#tabs-tabbar-container:is(.left, .right) .tab-strip::-webkit-scrollbar-button {
display: none !important;
}
#tabs-tabbar-container:is(.left, .right) .tab-strip::-webkit-scrollbar-thumb {
border: 2px solid transparent !important;
border-radius: 8px !important;
}
/*----- Vertical Tabbar Auto-Hide Behavior -----*/
/* Base hidden state for vertical tabbar */
#browser:is(.tabs-left, .tabs-right) .tabbar-wrapper {
position: absolute;
transform: translateX(calc(-100% + var(--tabbar-peek-width)));
transition: var(--tabbar-transition) !important;
opacity: 0;
z-index: 1;
}
/* Right side positioning */
#browser.tabs-right .tabbar-wrapper {
right: 0;
transform: translateX(calc(100% - var(--tabbar-peek-width)));
}
/* Tab move functionality support */
#browser.tabs-left.isblurred:where(:has(div.tab-yield-space, .tab-acceptsdrop)) .tabbar-wrapper,
#browser.tabs-left.isblurred:is(:active, :focus) .tabbar-wrapper:is(:active, :focus) {
transform: translateX(0);
opacity: 1;
}
/* Show tabbar on hover */
#browser:is(.tabs-left, .tabs-right) .tabbar-wrapper:hover {
transform: translateX(0);
transition: var(--tabbar-transition) !important;
opacity: 1;
}
/* Show when mouse approaches edge of screen */
#browser:is(.tabs-left) .mainbar:hover + .tabbar-wrapper,
#browser:is(.tabs-right) .webpage:hover + .tabbar-wrapper {
transform: translateX(0);
transition: var(--tabbar-transition) !important;
opacity: 1;
}
/* Show when workspace popups are active */
#browser:is(.tabs-left, .tabs-right):has(.WorkspacePopup:visible,
.workspace-popup:visible) .tabbar-wrapper {
transform: translateX(0);
transition: var(--tabbar-transition) !important;
opacity: 1;
}
/* Keep tab bar visible during workspace naming */
#browser:is(.tabs-left, .tabs-right):has(.quick-command-container.workspace-naming) .tabbar-wrapper,
#browser:is(.tabs-left, .tabs-right):has(.workspace-naming) .tabbar-wrapper,
#browser:is(.tabs-left, .tabs-right):has(.WorkspacePopup) .tabbar-wrapper,
#browser:is(.tabs-left, .tabs-right):has(input[placeholder*="workspace"]) .tabbar-wrapper {
transform: translateX(0) !important;
transition: none !important;
opacity: 1 !important;
}
/* Hide on click outside */
html:active:not(:has(.tabbar-wrapper:hover,
.quick-command-container.workspace-naming,
.workspace-naming,
input[placeholder="workspace"]:focus,
.WorkspacePopup:visible,
.workspace-popup:visible)) .tabbar-wrapper {
transform: translateX(calc(-100% + var(--tabbar-peek-width))) !important;
transition: var(--tabbar-transition) !important;
opacity: 0 !important;
}
/* Fix right side hiding behavior on click outside */
html:active:not(:has(.tabbar-wrapper:hover,
.quick-command-container.workspace-naming,
.workspace-naming,
input[placeholder="workspace"]:focus,
.WorkspacePopup:visible,
.workspace-popup:visible)) #browser.tabs-right .tabbar-wrapper {
transform: translateX(calc(100% - var(--tabbar-peek-width))) !important;
}
/* Additional reset mechanism for when tabs get stuck */
html:active:active .tabbar-wrapper:not(:hover):not(:has(.quick-command-container.workspace-naming,
.workspace-naming,
input[placeholder="workspace"]:focus)) {
transform: translateX(calc(-100% + var(--tabbar-peek-width))) !important;
opacity: 0 !important;
}
/* Additional reset for right side */
html:active:active #browser.tabs-right .tabbar-wrapper:not(:hover):not(:has(.quick-command-container.workspace-naming,
.workspace-naming,
input[placeholder="workspace"]:focus)) {
transform: translateX(calc(100% - var(--tabbar-peek-width))) !important;
opacity: 0 !important;
}
@amirulrodzi
Copy link

Hi, first of all, thank you so much, I really like this code which enables auto-hide of sidebar!

I am not good at CSS, so I may need your help a bit. In particular, I have a CSS that add 6px of padding to the browser (to make it look similar to Arc/Zen). Is there a way to amend your CSS code to enable show tabbar when hovering on the padding as well?

@Felvesthe
Copy link
Author

Hi, first of all, thank you so much, I really like this code which enables auto-hide of sidebar!

I am not good at CSS, so I may need your help a bit. In particular, I have a CSS that add 6px of padding to the browser (to make it look similar to Arc/Zen). Is there a way to amend your CSS code to enable show tabbar when hovering on the padding as well?

Give me yours CSS code, I will check if I can do anything for you.

@amirulrodzi
Copy link

amirulrodzi commented Oct 16, 2025

Here's my CSS file which is basically just Arcify from kaitpw. FYI, I am using tabbar on the right. Thanks in advance! :)


/* You MUST

  1. Have "Native Windows" disabled
  2. customize address bar to: flexible space, address bar, flexible space
  3. customize status bar to: status info (only this)
  4. customize the tab bar at the top to: flexible space, back, forward, reload. (the flex space is the crucial part here)
  5. make the command chain "Ctrl + 1" toggle both the address bar and the tab bar
    */

/* Arcify by adding padding to browser */
#browser {
padding: 6px !important;
}

/* Arcify by adding border radius and uniform inset shadow to main content container /
#webpage-stack {
border-radius: 6px;
box-shadow: inset 0 0 12px 0 rgba(0, 0, 0, 0.16);
/
Use backdrop-filter to increase saturation of content behind this element */
backdrop-filter: saturate(0.5);
-webkit-backdrop-filter: saturate(0.5);
}

.tabbar-wrapper {
/background: transparent !important;/

.tabbar-wrapper {
	background: transparent !important;
}

#tabs-tabbar-container {
	padding: 0 !important;
	padding-right: 5px !important;
	background: transparent !important;
	box-shadow: none !important;
}

#tabs-container {
	background: transparent !important;
}

}

/* Make header overlay at the very top, not affecting layout /
#browser #header {
/
position inside of the container gutter*/
position: absolute !important;
top: 0;
left: 0;
right: 0;
height: 20px !important;
background: transparent !important;
border: 0 !important;
box-shadow: none !important;
* {
color: transparent !important; /* avoid text rendering */
}
}

/* Arcify by collapsing mainbar height and remove padding/borders so it doesn't push UI /
.mainbar {
overflow: visible !important; /
let children escape */

/* position inside of the container gutter*/
position: absolute !important;
left: 0;
right: 0;

/* make resize area reasonably big and extend into the border of the browser */
top: -10px;
height: 20px !important;

/* make invisible */
border: 0 !important;
background: transparent !important;

/* let pointer events pass through (for forward/back/reload buttons) */
pointer-events: none !important;

}

#browser.win .mainbar {
.window-buttongroup {
position: absolute;
top: 50px;
right: clamp(6px, 6vw, 6px);
min-height: 0 !important;
pointer-events: none !important;
button {
width: 25px !important;
height: 25px !important;
pointer-events: auto;
}
}

button.vivaldi {
	display: none;
}

}

.mainbar {
.toolbar-mainbar {
transform: translateY(-40px);
}
}
#header {
.toolbar-mainbar {
/super jank but whatever/
transform: translate(20px, -20px);
}
}
.mainbar,
#header {
.UrlBar-AddressField {
opacity: 0;
transition: opacity 120ms ease;
max-width: 500px;
margin-top: calc(30% + 40px);
transform: scale(1.25) !important;
padding-left: 9px !important;

	&:not(:has(.UrlField:focus-within, #urlFieldInput:focus)) {
		pointer-events: none !important;
	}

	&:has(.UrlField:focus-within, #urlFieldInput:focus) {
		opacity: 1;
		pointer-events: auto;
	}

	.OmniDropdown {
		box-shadow: 0 0 40px 10px var(--colorHighlightBg, #fff4) !important;
		.OmniLinkItem {
			padding: 9px !important;
		}
	}
}

}

/* round the corners of the panel bar */
#panels-container {
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}

#footer {
background: transparent !important;
position: absolute !important;
bottom: -2px;
border: 0 !important;

/* Highlight status text when present */
.UrlFragments {
	background-color: var(--colorBg);
	padding: 2px 4px;
	border-radius: 3px;
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
	/* Only show when there's meaningful content */
	opacity: 0;
	transition: opacity 0.2s ease;
}

/* Show highlight when there's actual URL content */
.UrlFragments:not(:empty):has(.UrlFragment-LinkWrapper) {
	opacity: 1;
}

}

:root {
--tabbar-transition: transform .1s ease-out, opacity .1s ease-out;
--scrollbar-width: 10px;
--scrollbar-border-color: #9fb0cb;
--tabbar-peek-width: 3px;
}

/----- Scrollbar Styling -----/

#tabs-tabbar-container:is(.left, .right) .tab-strip::-webkit-scrollbar {
padding: 0 2px !important;
width: var(--scrollbar-width) !important;
border: 1px solid var(--scrollbar-border-color) !important;
border-radius: 8px !important;
}

#tabs-tabbar-container:is(.left, .right) .tab-strip::-webkit-scrollbar-button {
display: none !important;
}

#tabs-tabbar-container:is(.left, .right) .tab-strip::-webkit-scrollbar-thumb {
border: 2px solid transparent !important;
border-radius: 8px !important;
}

/----- Vertical Tabbar Auto-Hide Behavior -----/

/* Base hidden state for vertical tabbar */
#browser:is(.tabs-left, .tabs-right) .tabbar-wrapper {
position: absolute;
transform: translateX(calc(-100% + var(--tabbar-peek-width)));
transition: var(--tabbar-transition) !important;
opacity: 0;
z-index: 1;
}

/* Right side positioning */
#browser.tabs-right .tabbar-wrapper {
right: 0;
transform: translateX(calc(100% - var(--tabbar-peek-width)));
}

/* Tab move functionality support */
#browser.tabs-left.isblurred:where(:has(div.tab-yield-space, .tab-acceptsdrop)) .tabbar-wrapper,
#browser.tabs-left.isblurred:is(:active, :focus) .tabbar-wrapper:is(:active, :focus) {
transform: translateX(0);
opacity: 1;
}

/* Show tabbar on hover */
#browser:is(.tabs-left, .tabs-right) .tabbar-wrapper:hover {
transform: translateX(0);
transition: var(--tabbar-transition) !important;
opacity: 1;
}

/* Show when mouse approaches edge of screen */
#browser:is(.tabs-left) .mainbar:hover + .tabbar-wrapper,
#browser:is(.tabs-right) .webpage:hover + .tabbar-wrapper {
transform: translateX(0);
transition: var(--tabbar-transition) !important;
opacity: 1;
}

/* Show when workspace popups are active */
#browser:is(.tabs-left, .tabs-right):has(.WorkspacePopup:visible,
.workspace-popup:visible) .tabbar-wrapper {
transform: translateX(0);
transition: var(--tabbar-transition) !important;
opacity: 1;
}

/* Keep tab bar visible during workspace naming /
#browser:is(.tabs-left, .tabs-right):has(.quick-command-container.workspace-naming) .tabbar-wrapper,
#browser:is(.tabs-left, .tabs-right):has(.workspace-naming) .tabbar-wrapper,
#browser:is(.tabs-left, .tabs-right):has(.WorkspacePopup) .tabbar-wrapper,
#browser:is(.tabs-left, .tabs-right):has(input[placeholder
="workspace"]) .tabbar-wrapper {
transform: translateX(0) !important;
transition: none !important;
opacity: 1 !important;
}

/* Hide on click outside */
html:active:not(:has(.tabbar-wrapper:hover,
.quick-command-container.workspace-naming,
.workspace-naming,
input[placeholder="workspace"]:focus,
.WorkspacePopup:visible,
.workspace-popup:visible)) .tabbar-wrapper {
transform: translateX(calc(-100% + var(--tabbar-peek-width))) !important;
transition: var(--tabbar-transition) !important;
opacity: 0 !important;
}

/* Fix right side hiding behavior on click outside */
html:active:not(:has(.tabbar-wrapper:hover,
.quick-command-container.workspace-naming,
.workspace-naming,
input[placeholder="workspace"]:focus,
.WorkspacePopup:visible,
.workspace-popup:visible)) #browser.tabs-right .tabbar-wrapper {
transform: translateX(calc(100% - var(--tabbar-peek-width))) !important;
}

/* Additional reset mechanism for when tabs get stuck */
html:active:active .tabbar-wrapper:not(:hover):not(:has(.quick-command-container.workspace-naming,
.workspace-naming,
input[placeholder="workspace"]:focus)) {
transform: translateX(calc(-100% + var(--tabbar-peek-width))) !important;
opacity: 0 !important;
}

/* Additional reset for right side */
html:active:active #browser.tabs-right .tabbar-wrapper:not(:hover):not(:has(.quick-command-container.workspace-naming,
.workspace-naming,
input[placeholder="workspace"]:focus)) {
transform: translateX(calc(100% - var(--tabbar-peek-width))) !important;
opacity: 0 !important;
}
}

@BaalEvan
Copy link

BaalEvan commented Oct 22, 2025

Great Gist, unfortunately, there are issues with the tabs on the right. When closing a tab, everything shifts to the left by the size of the tab bar, making the tab bar visible.

Any hint on how to fix this would be greatly appreciated.

Here is "Fork" with my changes:

/*
    Custom CSS for Vivaldi Browser providing Arc Browser-like auto-hide functionality for vertical tabs.
    Fully compatible with workspaces.

    This customization was made and tested with the tab bar positioned on the left side of the screen,
    but it should also work on the right side.
*/

:root {
    --tabbar-transition: transform .2s ease-out, opacity .2s ease-out, background-color .2s ease-out, color .2s ease-out;
    --scrollbar-width: 10px;
    --scrollbar-border-color: #9fb0cb;
    --tabbar-peek-width: 32px;
    --backgroundBlur: blur(10px);
}

/*----- Scrollbar Styling -----*/

#tabs-tabbar-container:is(.left, .right) .tab-strip::-webkit-scrollbar {
    padding: 0 2px !important;
    width: var(--scrollbar-width) !important;
    border: 1px solid var(--scrollbar-border-color) !important;
    border-radius: 8px !important;
}

#tabs-tabbar-container:is(.left, .right) .tab-strip::-webkit-scrollbar-button {
    display: none !important;
}

#tabs-tabbar-container:is(.left, .right) .tab-strip::-webkit-scrollbar-thumb {
    border: 2px solid transparent !important;
    border-radius: 8px !important;
}

#app .tabs-left .button-toolbar.workspace-popup.tabbar-workspace-button button,
#app .tabs-right .button-toolbar.workspace-popup.tabbar-workspace-button button {
    /* height: 30px; */
    padding-left: 1px;
}

#browser .workspace-popup .button-icon:not(.audio) svg[width='16'],
#browser .WorkspacePopup .button-icon:not(.audio) svg[width='16'],
#browser .tabbar-workspace-button .button-icon:not(.audio) svg[width='16'],
#browser .workspace-popup .button-icon:not(:has(svg)):not(.audio),
#browser .WorkspacePopup .button-icon:not(:has(svg)):not(.audio),
#browser .tabbar-workspace-button .button-icon:not(:has(svg)):not(.audio) {
    margin: 0;
}

.tab {
    --colorBgAlphaHeavier: #ffffff11 !important;
}

/*----- Vertical Tabbar Auto-Hide Behavior -----*/

/* Base hidden state for vertical tabbar */
#browser:is(.tabs-left, .tabs-right) .tabbar-wrapper {
    position: absolute;
    transform: translateX(calc(-100% + var(--tabbar-peek-width)));
    transition: var(--tabbar-transition) !important;
    opacity: 1;
    z-index: 1;
    background-color: #101010;

}

#browser:is(.tabs-left, .tabs-right) .tabbar-wrapper .tab .title {
    color: transparent !important;
}

#browser:is(.tabs-left, .tabs-right) .tabbar-wrapper:hover .tab .title {
    color: white !important;
}


#browser .tab.active {
    background-color: var(--colorAccentBg) !important;
    color: var(--colorAccentFg) !important;
}

/* Right side positioning */
#browser.tabs-right .tabbar-wrapper {
    right: 0;
    /* transform: translateX(100); */
    /* transition-delay: 2s; */
    transform: translateX(calc(100% - var(--tabbar-peek-width)));
}

/* Tab move functionality support */
#browser.tabs-left.isblurred:where(:has(div.tab-yield-space, .tab-acceptsdrop)) .tabbar-wrapper,
#browser.tabs-left.isblurred:is(:active, :focus) .tabbar-wrapper:is(:active, :focus) {
    transform: translateX(0);
    opacity: 1;
    background-color: #00000033;

}

/* Show tabbar on hover */
#browser:is(.tabs-left, .tabs-right) .tabbar-wrapper:hover {
    transform: translateX(0);
    transition: var(--tabbar-transition) !important;
    opacity: 1;
    background-color: #00000033;

}

/* Show when mouse approaches edge of screen */
#browser:is(.tabs-left) .mainbar:hover+.tabbar-wrapper,
#browser:is(.tabs-right) .webpage:hover+.tabbar-wrapper {
    transform: translateX(0);
    transition: var(--tabbar-transition) !important;
    opacity: 1;
    background-color: #00000033;

}

/* Show when workspace popups are active */
#browser:is(.tabs-left, .tabs-right):has(.WorkspacePopup:visible,
    .workspace-popup:visible) .tabbar-wrapper {
    transform: translateX(0);
    transition: var(--tabbar-transition) !important;
    opacity: 1;
    background-color: #00000033;

}

/* Keep tab bar visible during workspace naming */
#browser:is(.tabs-left, .tabs-right):has(.quick-command-container.workspace-naming) .tabbar-wrapper,
#browser:is(.tabs-left, .tabs-right):has(.workspace-naming) .tabbar-wrapper,
#browser:is(.tabs-left, .tabs-right):has(.WorkspacePopup) .tabbar-wrapper,
#browser:is(.tabs-left, .tabs-right):has(input[placeholder*="workspace"]) .tabbar-wrapper {
    transform: translateX(0) !important;
    transition: none !important;
    opacity: 1 !important;
    background-color: #00000033;

}

/* Hide on click outside */
html:active:not(:has(.tabbar-wrapper:hover,
        .quick-command-container.workspace-naming,
        .workspace-naming,
        input[placeholder="workspace"]:focus,
        .WorkspacePopup:visible,
        .workspace-popup:visible)) .tabbar-wrapper {
    transform: translateX(calc(-100% + var(--tabbar-peek-width))) !important;
    transition: var(--tabbar-transition) !important;
    opacity: 0 !important;
}

/* Fix right side hiding behavior on click outside */
html:active:not(:has(.tabbar-wrapper:hover,
        .quick-command-container.workspace-naming,
        .workspace-naming,
        input[placeholder="workspace"]:focus,
        .WorkspacePopup:visible,
        .workspace-popup:visible)) #browser.tabs-right .tabbar-wrapper {
    transform: translateX(calc(100% - var(--tabbar-peek-width))) !important;
}

/* Additional reset mechanism for when tabs get stuck */
html:active:active .tabbar-wrapper:not(:hover):not(:has(.quick-command-container.workspace-naming,
        .workspace-naming,
        input[placeholder="workspace"]:focus)) {
    transform: translateX(calc(-100% + var(--tabbar-peek-width))) !important;
    opacity: 0 !important;
}

/* Additional reset for right side */
html:active:active #browser.tabs-right .tabbar-wrapper:not(:hover):not(:has(.quick-command-container.workspace-naming,
        .workspace-naming,
        input[placeholder="workspace"]:focus)) {
    transform: translateX(calc(100% - var(--tabbar-peek-width))) !important;
    opacity: 0 !important;
}```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment