Skip to content

Instantly share code, notes, and snippets.

@szalapski
Last active December 4, 2025 16:26
Show Gist options
  • Select an option

  • Save szalapski/d2677564a0e89f735d31 to your computer and use it in GitHub Desktop.

Select an option

Save szalapski/d2677564a0e89f735d31 to your computer and use it in GitHub Desktop.
TfsWebCompact neatens up the look-and-feel of your Azure DevOps web backlog and task board. See also http://www.szalapski.com/2014/05/a-compact-layout-for-tfs-web-work-items.html .
/* The following is a bookmarklet.
To actually use it, it is easier to drag-and-drop starting with my blog post:
http://www.szalapski.com/2014/05/a-compact-layout-for-tfs-web-work-items.html */
javascript:(function () {
const s = document.createElement('style');
s.innerText = `
/* version 2025-12-01 - see https://gist.githubusercontent.com/szalapski/d2677564a0e89f735d31 */
/* draw attention to button when full-screen */
.full-screen-mode button.bolt-button.subtle#__bolt-full-screen {
background-color: var(--palette-primary-darken-6);
color: white;
&:after {
content: 'Show navigation';
}
}
/* Make big green title bar shorter */
.project-header {
.region-header,
.region-header-menubar {
min-height: 20px;
.expandable-search-header {
padding-block: 0;
}
}
.me-control-div #me-control-container {
transform: scale(75%);
top: -40%;
.mectrl_topHeader .mectrl_profilepic {
margin-block: 0;
}
}
}
.bolt-header-with-commandbar:not(.boards-tabs-header) {
border-bottom: 1px solid lightgray;
}
.boards-tabs-header.bolt-header-with-commandbar {
width: 65%;
position: absolute;
left: 170px;
}
/* for backlog list */
#header-row {
display: none;
}
.header-section .hubs-section {
left: 300px;
top: -5px;
}
.bolt-page .page-content-top,
.board-wrapper .kanban-board .kanban-board-column-header,
.vss-FilterBar,
.bolt-page .padding-16,
.boards-tabbar-tabs,
.kanban-board-row-container .kanban-board-row,
.kanban-board-row-container .kanban-board-row .kanban-board-column-container {
margin-top: 0;
padding-top: 0;
margin-bottom: 0;
padding-bottom: 0;
}
.bolt-page > .bolt-header,
.nav-separated .hub-groups-section,
.nav-separated .search-box {
margin-top: 0;
padding-top: 0;
}
.bolt-page > .bolt-header {
margin-inline: 0;
}
.board-wrapper > .kanban-board.padding-horizontal-16,
.bolt-page .page-content-top.page-content {
padding-inline: 4px;
}
.header-post11 .hub-groups-section li,
.kanban-board-column-header-container.margin-bottom-4,
.bolt-page .page-content-bottom {
margin-bottom: 0;
padding-bottom: 0;
}
.bolt-header-title.title-m {
font-size: 1.1em;
}
.bolt-header-with-commandbar,
.kanban-board-column-header,
.board-column-item-count.font-size-l {
font-size: 75%;
}
.kanban-board-column-header span:has(.board-column-item-count) span {
font-size: 90%;
}
.bolt-button.icon-only.subtle {
padding: 2px
}
.header-post11 #navWrapper {
height: 20px;
}
.header-post11 + .content-section {
top: 20px;
}
.header-post11 .hub-groups-section {
padding-bottom: 0;
}
.hub-title {
padding-top: 9px;
padding-bottom: 9px;
}
.hub-content .right-hub-content .hub-pivot {
margin-left: 300px;
margin-right: 340px;
}
.hub-view.explorer .right-hub-content {
top: 3px;
}
.backlog-header .toolbar .menu-bar > .menu-item {
margin-top: 0;
margin-bottom: 0;
padding-top: 0;
padding-bottom: 0;
}
.backlog-header .toolbar .menu-bar > .menu-item.text-filter-box {
margin-top: 0 !important;
}
.backlog-header .toolbar .menu-bar > .menu-item.toggle-filter-bar {
padding-bottom: 0;
padding-top: 0 !important;
}
.backlog-header .toolbar .menu-bar > .menu-item.toggle {
margin-top: 0 !important;
}
.backlog-header .toolbar {
height: 25px;
margin-bottom: 0;
}
.backlog-header {
height: auto;
margin-bottom: 0;
}
.productbacklog-grid-results.sprint-backlog.grid {
margin-top: 0;
}
.grid-focus {
height: 0;
}
.bolt-tabbar-tabs.compact .bolt-tab {
height: 20px;
}
.bolt-filterbar-white {
border: 1px solid lightgray;
}
.grid-header-column > .title {
padding-top: 0;
}
.grid-row.closed-item-tfsWebCompact {
color: green;
}
.grid-row.closed-item-tfsWebCompact .grid-cell:nth-child(3) {
text-decoration: line-through;
}
/* for board */
.wit-card {
&:hover {
background-color: #efe;
}
&:focus {
background-color: #bfb;
&:hover {
background-color: #cfc;
}
}
.card-context-menu {
opacity: 50%;
top: 0;
right: 0;
}
.card-content {
padding: 4px 2px 4px 6px;
.work-item-type-icon{
margin-right: 0;
}
.annotation-row .fluent-icons-enabled:has(.work-item-type-icon){
display: none; /* hides the task icon entirely */
}
.identity-avatar.extra-extra-small{
margin-right: 2px;
}
}
.editable-field.is-identity {
min-height: 20px;
margin-top: 2px;
}
}
.ms-vss-web-vsts-theme-dark,
.ms-vss-web-vsts-theme-hc-dark {
.wit-card{
&:hover {
background-color: #242;
}
&:focus {
background-color: #464;
&:hover {
background-color: #474;
}
}
}
}
.id-title-container,
.board-content-details .task-list .add-task-container,
.agile-board .board-tile .board-tile-content .child-tasks-summary,
.board-content-details .task-list .task,
.tags.field-container,
.wit-card.boards-card .fields .field-container,
.wit-card.boards-card .work-item-state-container,
.card-content .annotations.margin-top-8,
.additional-field.lastAdditionalField,
.board-tile .container,
.taskboard-cell .id-title-container,
.taskboard-cell .witExtra,
.wit-card.taskboard-card .fields .field-container,
.wit-card .editable-card-identity-picker .card-assigned-to,
.wit-card.taskboard-card .work-item-state-container {
margin: 0
}
.wit-card.boards-card .fields .field-container > .label {
padding-inline: 5px;
width: fit-content;
}
.add-task-container,
.vss-Hub .vss-HubPivotBar,
.vss-PivotBar .vss-PivotBar--bar.tall .vss-PivotBar--commandBar,
.bolt-page > .bolt-header,
.flex.flex-column.rhythm-horizontal-4.padding-top-16 {
padding: 0;
}
.bolt-page .page-content {
padding-inline: 0;
}
.repos-pr-header.bolt-header,
.repos-pr-title input,
.pr-secondary-title-row,
.repos-compare-toolbar,
.vss-Hub .vss-HubPivotBar:not(.shadowStyle),
#taskboard-table-header th.taskboard-cell,
.bolt-tabbar-tabs.tall .bolt-tab,
.bolt-button {
padding-block: 0;
margin-block: 0;
height: auto;
}
.repos-changes-viewer .sticky,
.repos-compare-toolbar .margin-vertical-8,
.repos-changes-viewer.is-folder > :first-child {
padding-block: 2px;
margin-block: 2px;
}
.taskboard-card {
margin: 3px;
}
.navigation-container .flex-column {
width: 32px;
}
.project-navigation .navigation-icon {
width: 30px;
}
.vss-PivotBar .vss-PivotBar--pivots.tall .vss-PivotBar--button,
.vss-PivotBar .vss-PivotBar--bar.tall .vss-PivotBar--commandBar {
height: auto;
}
.tbTile {
width: 200px;
margin: 5px;
}
.tbTile.parentTbTile {
width: 140px;
}
.taskboard-parent {
min-width: auto;
width: 140px;
padding-right: 0;
}
.taskboard-expander {
width: 12px;
}
.taskboardTableHeaderScrollContainer .taskboard-parent {
min-width: 146px;
width: 140px;
padding-right: 0;
}
.taskboard-cell {
padding: 2px;
.id-title-container {
padding-right: 0;
}
.witExtra {
margin-bottom: 3px;
}
&:not(.taskboard-parent) .field-container.additional-field .field-label:first-child {
display: none;
}
}
.sprint-view-container .vss-PivotBar .vss-PivotBarItem.customPadding {
padding-inline: 5px;
}
.field-container.additional-field {
padding-left: 4px;
}
.wit-card.boards-card .annotations .annotation-expanded {
position: relative;
.annotation-button.checklist {
margin-top: 0;
position: absolute;
top: -18px;
right: 0;
padding-inline: 40px;
}
}
/* enlarge the assignee photo and move other things around to compensate */
.editable-card-identity-picker {
.identity-view {
align-items: start;
}
.vss-Persona {
width: 40px;
height: 40px;
}
}
.wit-card .card-content {
padding-left: 0;
& > .flex-row {
padding-left: 4px;
}
.editable-card-identity-picker {
margin-top: 0;
}
}
/* tags list on a card (right-justified) */
.card-content {
.tags-list {
position: relative;
div[aria-label='Tags list'] {
position: absolute;
right: 0px;
bottom: 0px;
}
.bolt-pill {
margin-bottom: 0;
}
}
/* tags list on a card with assignee (move up) */
&:has(.is-identity) .tags-list {
margin-top: 0;
top: -20px;
}
}
/* task list neatening given the bigger assignee photo above */
.kanban-board-column-container .kanban-board-column .wit-card.boards-card .annotations {
button.annotation {
padding: 5px;
&:not(.active) {
position: absolute;
bottom: 0px;
left: 50px;
}
}
table.body-s {
margin-top: 0;
}
}
/* make the Closed column really compact */
td[axis='taskboard-table-body_s2'] {
.tbTile {
font-size: 10.5px;
.id {
line-height: 10px;
}
.title {
line-height: 12px;
}
.id-title-container {
line-height: 10px;
}
.tbTileContent .container.witExtra {
max-height: 12px;
}
}
.witExtra {
height: 18px;
.user-picture-resolved {
display: none;
}
.element-height-medium {
line-height: unset;
}
}
.work-item-type-icon-host {
display: none;
}
}
.kanban-board-content > div:last-child {
.wit-card {
margin-top: 1px;
font-size: 10.5px;
line-height: 11px;
.editable-field.is-identity {
min-height: unset;
}
.card-content {
padding-block: 3px;
}
}
.wit-ui-control.identity-view .identity-avatar {
display: none;
}
}
/* row numbers on task board */
table.sticky-table {
counter-reset: number;
td .taskboard-expand-collapse-button {
position: relative;
counter-increment: number;
&:after {
position: absolute;
writing-mode: vertical-rl;
/* fallback for browsers that don't support sideways-lr */
writing-mode: sideways-lr;
white-space: nowrap;
font-size: 120%;
content: 'ROW ' counter(number);
top: 30px;
}
}
td.taskboard-collapsed-row .taskboard-expand-collapse-button:after {
/* smaller and tighter on collapsed rows */
top: 0;
left: 14px;
font-size: 80%;
writing-mode: unset;
content: counter(number);
}
}
/* Avoid light font colors on board (e.g. with medium color background) */
.wit-card.boards-card .fields .field-container .value {
width: 70%;
a.bolt-link.light,
a.bolt-link.light:hover {
color: var(--communication-foreground);
}
}
/* If there are no swimlanes (no .kanban-board-column-container), make a double-width third column (Active) */
.board-wrapper .kanban-board:not(:has(.kanban-board-column-container)){
.kanban-board-column,
.kanban-board-column-header {
max-width: 291px;
min-width: 183px;
&:nth-child(3) {
max-width: 582px;
min-width: 386px;
.wit-card {
width: calc(50% - 16px);
}
/* makes several per row, instead of column */
flex-direction: row;
/* makes the rows wrap */
flex-wrap: wrap;
/* keeps the vertical space between rows to a minimum */
align-content: flex-start;
/* keeps the height of each card to a minimum */
align-items: flex-start;
}
}
}
/* relative card number labels on story board */
.kanban-board-content {
counter-reset: col1 col2 col3 col4 col5;
.boards-card {
position: relative;
&:after {
position: absolute;
writing-mode: vertical-rl;
/* fallback for browsers that don't support sideways-lr */
writing-mode: sideways-lr;
white-space: nowrap;
left: -14px;
top: 8px;
}
}
.main-column-container:nth-child(1) .boards-card,
.kanban-board-column:nth-child(1) .boards-card {
counter-increment: col1;
&:after {
content: 'BACKLOG ' counter(col1);
}
}
.kanban-board-row-container .kanban-board-column-container .kanban-board-column:nth-child(1) .boards-card,
.kanban-board-column:nth-child(2) .boards-card {
counter-increment: col2;
&:after {
content: 'UP NEXT ' counter(col2);
}
}
.kanban-board-row-container .kanban-board-column-container .kanban-board-column:nth-child(2) .boards-card,
.kanban-board-column:nth-child(3) .boards-card {
counter-increment: col3;
&:after {
content: 'ACTIVE ' counter(col3);
}
}
.kanban-board-row-container .kanban-board-column-container .kanban-board-column:nth-child(3) .boards-card,
.kanban-board-column:nth-child(4) .boards-card {
counter-increment: col4;
&:after {
content: 'REVIEW ' counter(col4);
}
}
.main-column-container:nth-child(3) .boards-card,
.kanban-board-column:nth-child(5) .boards-card {
counter-increment: col5;
&:after {
content: 'CLOSED ' counter(col5);
left: -11px;
top: 5px;
}
}
}`;
document.head.appendChild(s);
document.getElementById('__bolt-full-screen')?.click();
enhancePhotos();
})();
function enhancePhotos(){
for (img of $('.vss-Persona-content.using-image')) img.src = img.src.replace('size=0', 'size=2');
}
@szalapski
Copy link
Author

Easier to use if you start from the blog post.

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