Reputation: 23008
I have prepared a complete and simple jsFiddle for my question.
My word game currently uses an HTML table for laying out HTML canvas and jQuery UI buttons.
I would like to get rid of the HTML table and instead use HTML div elements, which I have written out in the red/yellow boxes with arrows at the screenshot:
I would like to have the following structure of the div elements:
- fullDiv (should occupy 100% width and height of browser window)
-- hintDiv (100% width, min height, visible on top)
-- mainDiv (100% width, max height)
--- gameDiv (100% width, max height)
---- myCanvas (100% width, max height)
-- leftDiv (min width, same height as mainDiv, scrollable) <- relative position
-- rightDiv (min width, same height as mainDiv) <- relative position
-- totalDiv (100% width, min height, visible on bottom)
The idea is to give myCanvas
as much space as possible and place leftDiv
and rightDiv
as kind of "menus" of both sides of it. The leftDiv
would be a navigational menu with a scrollable list of games and have the same max possible height as myCanvas
and rightDiv
.
So I have tried the following code -
$(function () {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)'
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
}
gamesMenu.menu('refresh');
});
body {
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
}
#hintDiv,
#totalDiv {
text-align: center;
}
#mainDiv,
#gameDiv {
width: 100%;
height: 100%;
}
#myCanvas {
width: 100%;
height: 100%;
border: 4px red dotted;
background: #CCF;
}
#leftDiv {
position: relative;
left: 0;
top: 0;
/* bottom: 0; */
text-align: center;
background: #FCC;
}
#rightDiv {
position: relative;
right: 0;
top: 0;
/* bottom: 0; */
text-align: center;
background: #CFC;
}
#gamesMenu {
overflow-y: scroll;
}
#hintDiv {
font-style: italic;
}
<div id="fullDiv">
<div id="hintDiv">Hint</div>
<div id="mainDiv">
<div id="gameDiv">
<canvas id="myCanvas"></canvas>
</div>
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="rightDiv">
<input id="fullCheck" type="checkbox">
<label for="fullCheck">Full screen</label><br>
<button id="recallBtn">Recall</button><br>
<button id="shuffleBtn">Shuffle</button><br>
<button id="swapBtn">Swap</button><br>
<button id="skipBtn">Skip</button><br>
<button id="resignBtn">Resign</button><br>
<button id="pileBtn">Pile</button><br>
<button id="movesBtn">Moves history</button><br>
<button id="shareBtn">Share</button><br>
<button id="playBtn">Play</button>
</div>
</div>
<div id="totalDiv">Total</div>
</div>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
However, my screen is totally messed up now:
myCanvas
, leftDiv
and rightDiv
are placed after each other instead of leftDiv
/rightDiv
covering myCanvas
on its both sidesmyCanvas
occupies the whole browser window, pushing hintDiv
/totalDiv
out of screengamesMenu
is displayed in its whole glory instead of being scrollableUPDATE:
Here the solution by Derek (thank you!)
$(function () {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)'
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
}
gamesMenu.menu('refresh');
});
body {
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
display: flex;
flex-direction: column;
}
#hintDiv,
#totalDiv {
text-align: center;
background: yellow;
}
#leftDiv {
text-align: center;
background: #FCC;
display: flex;
flex-direction: column;
}
#gamesMenu {
overflow-y: auto;
}
#mainDiv {
flex-grow: 1;
display: flex;
justify-content: space-between;
overflow: hidden;
}
#gameDiv {
flex-grow: 1;
}
#myCanvas {
width: 100%;
height: 100%;
box-sizing: border-box;
border: 4px red dotted;
background: #CCF;
}
#rightDiv {
text-align: center;
background: #CFC;
overflow-y: auto;
}
#hintDiv {
font-style: italic;
}
<div id="fullDiv">
<div id="hintDiv">Hint</div>
<div id="mainDiv">
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="gameDiv">
<canvas id="myCanvas"></canvas>
</div>
<div id="rightDiv">
<input id="fullCheck" type="checkbox">
<label for="fullCheck">Full screen</label><br>
<button id="recallBtn">Recall</button><br>
<button id="shuffleBtn">Shuffle</button><br>
<button id="swapBtn">Swap</button><br>
<button id="skipBtn">Skip</button><br>
<button id="resignBtn">Resign</button><br>
<button id="pileBtn">Pile</button><br>
<button id="movesBtn">Moves history</button><br>
<button id="shareBtn">Share</button><br>
<button id="playBtn">Play</button>
</div>
</div>
<div id="totalDiv">Total</div>
</div>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
UPDATE 2:
For some reason jQuery UI menu is not hoverable (eventhough in the official demo it is)...
My workaround sofar is (to at least see the selected item):
li.selected {
font-weight: bold;
background-color: yellow;
}
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)',
select: function(ev, ui) {
ui.item.addClass('selected').siblings().removeClass('selected');
}
});
Upvotes: 1
Views: 118
Reputation: 10204
This can be accomplished using flex layout.
#fullDiv
to use flex
layout with flex-direction: column
so that it can be aligned on columns.flex: 1 1 auto
to #mainDiv
so that it can take the space except the #hintDiv
and #totalDiv
on #fullDiv
.#mainDiv
to flex
layout too with justify-content: space-between
. You will know about that on this guide.#leftDiv
and #gameDiv
.#gameDiv
, I have updated the canvas width and height as calc(100% - 8px)
because the border size will be added to the real canvas size. So now, canvas border width is 4px so the canvas width will be (100% - 8px) + 8px(border size) = 100%
./*$(function () {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)'
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
}
});*/
body {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
}
#hintDiv,
#totalDiv {
text-align: center;
}
#myCanvas {
width: calc(100% - 8px);
height: calc(100% - 8px);
border: 4px red dotted;
background: #CCF;
}
#leftDiv {
text-align: center;
background: #FCC;
}
#rightDiv {
text-align: center;
background: #CFC;
}
#gamesMenu {
overflow-y: scroll;
}
#publishBtn {
max-width: 200px;
}
#timer1,
#timer2 {
color: red;
}
#hintDiv {
font-style: italic;
}
/*** Additional Codes ***/
#fullDiv {
display: flex;
flex-direction: column;
}
#mainDiv {
flex: 1 1 auto;
display: flex;
justify-content: space-between;
}
#gameDiv {
flex: 1 1 auto;
}
<div id="fullDiv">
<div id="hintDiv">Hint</div>
<div id="mainDiv">
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="gameDiv">
<canvas id="myCanvas"></canvas>
</div>
<div id="rightDiv">
<input id="fullCheck" type="checkbox">
<label for="fullCheck">Full screen</label><br>
<button id="recallBtn">Recall</button><br>
<button id="shuffleBtn">Shuffle</button><br>
<button id="swapBtn">Swap</button><br>
<button id="skipBtn">Skip</button><br>
<button id="resignBtn">Resign</button><br>
<button id="pileBtn">Pile</button><br>
<button id="movesBtn">Moves history</button><br>
<button id="shareBtn">Share</button><br>
<button id="playBtn">Play</button>
</div>
</div>
<div id="totalDiv">Total</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Upvotes: 3