Reputation: 22988
I have prepared a simple test case (below), which uses a nested CSS flexbox to give max possible space to the checkered #pixiCanvas
, while keeping the yellow #hintDiv
and #totalDiv
at the screen top/bottom:
The problem is that while my code works perfectly on other browsers (Firefox, Chrome, Opera, Edge, even IE 11; after I have followed the advice to add min-width
, min-height
to #mainDiv
and its children) it does not work with Safari 14 / MacOS -
The #mainDiv
or maybe #gameDiv
grow too tall and push #totalDiv
out of the screen, while #pixiCanvas
is cut off and not displayed entirely:
The structure of my web page is:
- fullDiv (should occupy 100% / 100 vh)
-- leftDiv
-- mainDiv
--- hintDiv (100% width, on top of screen)
--- gameDiv (should have max possible width and height)
--- totalDiv (100% width, on bottom of screen)
-- rightDiv
Here is my code (open in Safari to see the issue):
$(function() {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)',
select: function(ev, ui) {
ui.item.addClass('selected').siblings().removeClass('selected');
}
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI CLASS="ui-menu-item-wrapper" VALUE="' + game + '">GAME ' + game + '</LI>');
}
gamesMenu.menu('refresh');
var WIDTH = 400;
var HEIGHT = 400;
var app = new PIXI.Application({
width: WIDTH,
height: HEIGHT,
view: document.getElementById('pixiCanvas'),
backgroundColor: 0xFFFFFF
});
var background = new PIXI.Graphics();
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 8; j++) {
if ((i + j) % 2 == 0) {
background.beginFill(0xCCCCFF);
background.drawRect(i * WIDTH / 8, j * HEIGHT / 8, WIDTH / 8, HEIGHT / 8);
background.endFill();
}
}
}
app.stage.addChild(background);
});
body {
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
display: flex;
}
#hintDiv,
#totalDiv {
font-style: italic;
text-align: center;
background: yellow;
}
#leftDiv {
text-align: center;
background: #FCC;
display: flex;
flex-direction: column;
}
#gamesMenu {
overflow: auto;
}
#mainDiv {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
min-width: 200px;
min-height: 200px;
box-sizing: border-box;
border: 1px green dashed;
}
#gameDiv {
flex-grow: 1;
min-width: 150px;
min-height: 150px;
}
#pixiCanvas {
width: 100%;
height: 100%;
min-width: 100px;
min-height: 100px;
background: #CCF;
box-sizing: border-box;
border: 4px red dotted;
}
#rightDiv {
text-align: center;
background: #CFC;
overflow-y: auto;
}
li.selected {
font-weight: bold;
background-color: yellow;
}
<div id="fullDiv">
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="mainDiv">
<div id="hintDiv">Hint</div>
<div id="gameDiv">
<canvas id="pixiCanvas"></canvas>
</div>
<div id="totalDiv">Total score</div>
</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>
<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>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/pixi.min.js"></script>
Here the screenshot of my word game, where the #pixiCanvas
grows too large and is shown underneath the grey chat area at the bottom:
The only workaround I have been able to come up sofar has been:
if (navigator.userAgent.indexOf('Safari') >= 0) {
$('#gameDiv').css('overflow', 'auto');
}
but it makes the usage of my word game awkward while dragging letters.
P.S. I would prefer not to switch to CSS grid, because I have an impression that CSS flex is better supported (and some of my users still use IE 11).
Upvotes: 1
Views: 1610
Reputation: 6348
Simply add display: contents;
to #gameDiv
:
#gameDiv{
display: contents;
}
Browser compatibility for display contents
As you can see this display is not compatible with IE. But this is fine because IE will ignore it and apply default display: block
that works fine in IE (I tested it).
Any if you want it to be sure to apply the right display, you can still keep display: block
by using 2 display as in this subject.
Using:
@supports (display: contents) {
#gameDiv { display: contents; }
}
Demo:
$(function() {
$(':button').button();
$('#fullCheck').checkboxradio();
var gamesMenu = $('#gamesMenu').menu({
items: '> :not(.ui-widget-header)',
select: function(ev, ui) {
ui.item.addClass('selected').siblings().removeClass('selected');
}
});
for (var game = 1; game <= 50; game++) {
gamesMenu.append('<LI CLASS="ui-menu-item-wrapper" VALUE="' + game + '">GAME ' + game + '</LI>');
}
gamesMenu.menu('refresh');
var WIDTH = 400;
var HEIGHT = 400;
var app = new PIXI.Application({
width: WIDTH,
height: HEIGHT,
view: document.getElementById('pixiCanvas'),
backgroundColor: 0xFFFFFF
});
var background = new PIXI.Graphics();
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 8; j++) {
if ((i + j) % 2 == 0) {
background.beginFill(0xCCCCFF);
background.drawRect(i * WIDTH / 8, j * HEIGHT / 8, WIDTH / 8, HEIGHT / 8);
background.endFill();
}
}
}
app.stage.addChild(background);
});
body {
margin: 0;
padding: 0;
}
#fullDiv {
width: 100%;
height: 100vh;
background: #FFF;
display: flex;
}
#hintDiv,
#totalDiv {
font-style: italic;
text-align: center;
background: yellow;
}
#leftDiv {
text-align: center;
background: #FCC;
display: flex;
flex-direction: column;
}
#gamesMenu {
overflow: auto;
}
#mainDiv {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
min-width: 200px;
min-height: 200px;
box-sizing: border-box;
border: 1px green dashed;
}
#gameDiv {
flex-grow: 1;
min-width: 150px;
min-height: 150px;
}
#pixiCanvas {
width: 100%;
height: 100%;
min-width: 100px;
min-height: 100px;
background: #CCF;
box-sizing: border-box;
border: 4px red dotted;
}
#rightDiv {
text-align: center;
background: #CFC;
overflow-y: auto;
}
li.selected {
font-weight: bold;
background-color: yellow;
}
#gameDiv{
display: contents;
}
<div id="fullDiv">
<div id="leftDiv">
<button id="newBtn">New game</button>
<ul id="gamesMenu"></ul>
</div>
<div id="mainDiv">
<div id="hintDiv">Hint</div>
<div id="gameDiv">
<canvas id="pixiCanvas"></canvas>
</div>
<div id="totalDiv">Total score</div>
</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>
<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>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/pixi.min.js"></script>
Upvotes: 2