JSFiddle - React, Tailwind, and code Playground
by baacke
HTML
<div class="bracket">
<table>
<tbody>
<!-- APPEND HERE -->
</tbody>
</table>
</div>
CSS
.bracket table {border-collapse: collapse;
border-spacing: 0;
color: #000}
.bracket td {text-align: center;
height: 25px;
width: 200px;
position: relative;}
.bracket td.winner {border: 0}
/*.bracket td div {height: 54%} Now Set Inline During Bracket Creation for IE8 Compatability */
.bracket td div.left{border-right: 2px solid #333;
border-top: 2px solid #333;
border-bottom: 2px solid #333;
border-radius: 0 2px 2px 0}
.bracket td div.right{border-left: 2px solid #333;
border-top: 2px solid #333;
border-bottom: 2px solid #333;
border-radius: 0 2px 2px 0}
.bracket td div.first,
.bracket td div.last {height: 95%}
.bracket td div.bye {display: none}
.bracket td div span {display: block;
width: 100%;
text-align: center;
position: absolute;
margin: 0 auto -11px;
bottom: 50%;
cursor: pointer}
.bracket td div.winner span {cursor: default}
.bracket td div span.tbd {cursor: default;
color: #949494;
font-size: 10px;
margin-bottom: -5px;
text-transform: uppercase}
JavaScript
var maxFullRoundGames = 1,
rowsNeeded = null,
colsNeeded = null,
divHeight = 30; //in px (for IE8 height)
tbody = $('div.bracket table tbody'),
teams = [];
var totalTeams = /*teams.length - 2;*/ Number( prompt("how many teams?") );
for( ; (maxFullRoundGames * 2) < totalTeams ; )
{ maxFullRoundGames *= 2; }
var reqFirstRoundGames = totalTeams - maxFullRoundGames;
var reqFirstRoundByes = totalTeams - (reqFirstRoundGames * 2);
/* Determine Number of Table Rows Required */
if( totalTeams % maxFullRoundGames > 0 )
{ rowsNeeded = maxFullRoundGames; }
else
{ rowsNeeded = totalTeams / 2; }
/* Create Pattern for ColSpan */
var colPattern = [1];
for( var c = 2; c <= rowsNeeded; c *= 2 ){
for ( var p = 0 ; p < c - (c / 2) ; p++ ){
colPattern.push( colPattern[p] );
}
colPattern[0] = colPattern[0] + 1;
}
/* Define Pattern for Seeding */
var left = [],
right = [];
for(var z = 1, i = 1, current = 'left' ; i <= rowsNeeded*2 ; i++){
if( current == 'left' ){
left.push(i)
}else{ //current == 'right'
right.push(i)
}
if( z == 1 ){
if( current == 'left' ){
current = 'right';
}else{
current = 'left';
}
z = 0;
}else{
z++;
}
}
var seeds = { 'left' : [],
'right' : [] };
var one = seedingSide(left.length);
for(var c=0 ; c < one.length ; c++){
seeds.left.push(left[one[c]-1]);
seeds.right.push(right[one[c]-1]);
}
function seedingSide(numPlayers){
var rounds = Math.log(numPlayers)/Math.log(2)-1;
var pls = [1,2];
for(var i=0;i<rounds;i++){
pls = nextLayer(pls);
}
return pls;
function nextLayer(pls){
var out=[];
var length = pls.length*2+1;
pls.forEach(function(d){
out.push(d);
out.push(length-d);
});
return out;
}
}
/* Create Each Row */
for( var row = 1 ; row <= rowsNeeded ; row++ ) {
var colsNeeded = colPattern[(row-1)],
rowspan = 1,
...