Last active
October 14, 2025 19:53
-
-
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 .
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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-10-14 - 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; } | |
| .full-screen-mode button.bolt-button.subtle#__bolt-full-screen: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-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:focus{ background-color: #bfb; } | |
| .wit-card:focus:hover{ background-color: #cfc; } | |
| .wit-card:hover{ background-color: #efe; } | |
| .wit-card .card-context-menu { opacity: 50%; top:0; right:0; } | |
| .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; } | |
| .wit-card .card-content{padding: 4px 6px;} | |
| .wit-card .editable-field.is-identity{min-height: 20px; margin-top: 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;} | |
| .taskboard-cell .id-title-container{ padding-right:0; } | |
| .taskboard-cell .witExtra { margin-bottom: 3px;} | |
| .taskboard-cell: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;} | |
| .wit-card.boards-card .annotations .annotation-expanded .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: 45px; | |
| height:45px; | |
| } | |
| } | |
| .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; | |
| } | |
| button.annotation: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;} | |
| .tbTile .id {line-height:10px;} | |
| .tbTile .title {line-height:12px;} | |
| .tbTile .id-title-container {line-height: 10px;} | |
| .tbTile .tbTileContent .container.witExtra { max-height: 12px; } | |
| .witExtra {height:18px;} | |
| .witExtra .user-picture-resolved { display:none;} | |
| .witExtra .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; } | |
| .wit-card .editable-field.is-identity { min-height: unset; } | |
| .wit-card .card-content { padding-block: 3px; } | |
| .wit-ui-control.identity-view .identity-avatar {display:none;} | |
| } | |
| /* "make a column narrower - keeping in case we want to bring it back */ | |
| /* | |
| table.sticky-table colgroup col:nth-child(5){ | |
| width: 12.5% !important; | |
| } | |
| */ | |
| /* row numbers on task board */ | |
| table.sticky-table{ | |
| counter-reset: number; | |
| } | |
| table.sticky-table td .taskboard-expand-collapse-button{ | |
| position:relative; | |
| counter-increment: number; | |
| } | |
| table.sticky-table td .taskboard-expand-collapse-button: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; | |
| } | |
| table.sticky-table 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); | |
| } | |
| /* relative card number labels on story board */ | |
| .kanban-board-content { | |
| counter-reset: backlog upnext hold active testing closed; | |
| } | |
| .kanban-board-content .main-column-container .boards-card, | |
| .kanban-board-row-container .kanban-board-column-container .kanban-board-column .boards-card{ | |
| position:relative; | |
| } | |
| .kanban-board-content .main-column-container .boards-card:after, | |
| .kanban-board-row-container .kanban-board-column-container .kanban-board-column .boards-card:after{ | |
| position: absolute; | |
| writing-mode: vertical-rl; /* fallback for browsers that don't support sideways-lr */ | |
| writing-mode: sideways-lr; | |
| white-space: nowrap; | |
| left: -13px; | |
| top: 8px; | |
| } | |
| .kanban-board-content .main-column-container:nth-child(1) .boards-card { counter-increment: backlog; } | |
| .kanban-board-content .main-column-container:nth-child(1) .boards-card:after { content:"BACKLOG " counter(backlog); } | |
| .kanban-board-row-container .kanban-board-column-container .kanban-board-column:nth-child(1) .boards-card { counter-increment: upnext; } | |
| .kanban-board-row-container .kanban-board-column-container .kanban-board-column:nth-child(1) .boards-card:after { content:"UP NEXT " counter(upnext); } | |
| .kanban-board-row-container .kanban-board-column-container .kanban-board-column:nth-child(2) .boards-card { counter-increment: hold; } | |
| .kanban-board-row-container .kanban-board-column-container .kanban-board-column:nth-child(2) .boards-card:after { content:"ACTIVE " counter(hold); } | |
| .kanban-board-row-container .kanban-board-column-container .kanban-board-column:nth-child(3) .boards-card { counter-increment: active; } | |
| .kanban-board-row-container .kanban-board-column-container .kanban-board-column:nth-child(3) .boards-card:after { content:"IN TEST " counter(active); } | |
| .kanban-board-content .main-column-container:nth-child(3) .boards-card { counter-increment: closed; } | |
| .kanban-board-content .main-column-container:nth-child(3) .boards-card:after { content:"CLOSED " counter(closed); } | |
| `; | |
| 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"); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Easier to use if you start from the blog post.