【问题标题】:Can relative positioning be used within flexboxes?可以在弹性盒中使用相对定位吗?
【发布时间】:2018-10-25 23:56:11
【问题描述】:

Image showing overview of problem

我正在制作模块化的行/列布局,其中行中的列中的行的可变组合等。我正在使用 flex 属性使这些元素很好地适合页面。

CSS:

.row {
    display: flex;
}
.column {
    display: flex;
    flex-direction: column;
    flex: 1;
}

Here is a fiddle showing the effect I'm going for。请注意,列的大小与其内容成比例。

但是,我也使用 canvas 元素,为了实现多个绘图层,我将它们堆叠起来:

CSS:

.canvasarea {
    position: relative;
}
.canvasarea canvas {
    position: absolute;
}

Here's a fiddle showing this effect.

但是,当我尝试组合这些效果时,我得到了this unexpected result (fiddle)。它现在将列宽设置为屏幕的 50%,而不考虑子元素。

我已经尝试了所有我能找到的 flexposition 选项,但似乎无法将这两种效果放在一起。是否可以这样做,或者我是否通过使用 relative 来破坏 flex?我会很感激任何提示,我还是 CSS 新手。

【问题讨论】:

  • 在第三个示例中,您使用的是flex: 50%;,为什么会这样?
  • @Abinthaha 很好——我最初使用的示例指定了flex: 50%;,但在阅读后我意识到 50% 是任意的,它可以是任何正数并且功能相同(据我所知知道)。

标签: javascript html css canvas flexbox


【解决方案1】:

flex: 1 设置为.canvasarea 以适应弹性容器中的可用空间,并将max-width: 100% 设置为canvas 元素以防止溢出:

var canvas1b = document.getElementById("cvs1back");
canvas1b.height = 400;
canvas1b.width = 400;
var ctx1b = canvas1b.getContext("2d");
ctx1b.fillStyle = "red";
ctx1b.fillRect(0, 0, canvas1b.width, canvas1b.height);

var canvas1f = document.getElementById("cvs1front");
canvas1f.height = 400;
canvas1f.width = 400;
var ctx1f = canvas1f.getContext("2d");
ctx1f.beginPath();
ctx1f.moveTo(0, 0);
ctx1f.lineTo(0, 0);
ctx1f.stroke();

var canvas2b = document.getElementById("cvs2back");
canvas2b.height = 400;
canvas2b.width = 400;
var ctx2b = canvas2b.getContext("2d");
ctx2b.fillStyle = "blue";
ctx2b.fillRect(0, 0, canvas2b.width, canvas2b.height);

var canvas2f = document.getElementById("cvs2front");
canvas2f.height = 400;
canvas2f.width = 400;
var ctx2f = canvas2f.getContext("2d");
.row {
  display: flex;
}

.column {
  flex: 1;
}

.canvasarea {
  position: relative;
  flex: 1;
}

.canvasarea canvas {
  position: absolute;
  max-width: 100%;
}

span {
  background: yellow;
}
<div class="row">
  <span>Some text</span>
</div>
<div class="row">
  <div class="column">
    <div class="canvasarea">
      <canvas id="cvs1back"></canvas>
      <canvas id="cvs1front"></canvas>
    </div>
  </div>
  <div class="column">
    <div class="row">
      <span>Some other text</span>
    </div>
    <div class="row">
      <div class="canvasarea">
        <canvas id="cvs2back"></canvas>
        <canvas id="cvs2front"></canvas>
      </div>
    </div>
  </div>
</div>

【讨论】:

  • 啊哈!这看起来很棒,尽管它仍然强制列拆分为宽度的 50%。在我的第一个链接小提琴中,flex 允许第一列在屏幕很小的情况下以全宽(本例中为 400 像素)运行。这可以重现吗?
  • @mirrorcoloured 您可以使用媒体查询来调整元素在较小屏幕上的分层方式 - @media screen and (max-width: 500px) { .row { flex-direction: column; } }。假设这是你所追求的,如果不是,请纠正我。
  • this example 中是我想要的行为,而目前它看起来像this。在我看来,我的两列总是各占可用宽度的 50%,但我希望它们的宽度只有它们需要的宽度(如第一个示例中所示)。 Fiddle with current code
【解决方案2】:

我发现将min-width 设置为最宽元素的宽度(在本例中是我的画布)achieved the desired effect

HTML:

<div class="row">
  <span>Some text</span>
</div>
<div class="row">
  <div class="column">
    <div class="row">
      <div style="min-width:300px" class ="canvasarea">
        <canvas id="cvs1back"></canvas>
        <canvas id="cvs1front"></canvas>
      </div>
    </div>
  </div>
  <div class="column">
    <div class="row">
      <span>Some other text</span>
    </div>
    <div class="row">
      <div style="min-width:100px" class ="canvasarea">
        <canvas id="cvs2back"></canvas>
        <canvas id="cvs2front"></canvas>
      </div>
    </div>
  </div>
</div>

CSS:

.row {
    display: flex;
    flex-direction: row;
}
.column {
    display: flex;
    flex-direction: column;
    flex: 1;
}

.canvasarea {
  position: relative;
}
.canvasarea canvas {
  position: absolute;
}

JS:

var canvas1size = 300;
var canvas1b = document.getElementById("cvs1back");
canvas1b.height = canvas1size;
canvas1b.width = canvas1size;
var ctx1b = canvas1b.getContext("2d");
ctx1b.fillStyle = "red";
ctx1b.fillRect(0, 0, canvas1b.width, canvas1b.height);

var canvas1f = document.getElementById("cvs1front");
canvas1f.height = canvas1size;
canvas1f.width = canvas1size;
var ctx1f = canvas1f.getContext("2d");
ctx1f.beginPath();
ctx1f.strokeStyle = "black";
ctx1f.moveTo(canvas1size,0);
ctx1f.lineTo(0,canvas1size);
ctx1f.stroke();

canvas2size = 100;
var canvas2b = document.getElementById("cvs2back");
canvas2b.height = canvas2size;
canvas2b.width = canvas2size;
var ctx2b = canvas2b.getContext("2d");
ctx2b.fillStyle = "gray";
ctx2b.fillRect(0, 0, canvas2b.width, canvas2b.height);

var canvas2f = document.getElementById("cvs2front");
canvas2f.height = canvas2size;
canvas2f.width = canvas2size;
var ctx2f = canvas2f.getContext("2d");
ctx2f.beginPath();
ctx2f.strokeStyle = "black";
ctx2f.moveTo(0,0);
ctx2f.lineTo(canvas2size,canvas2size);
ctx2f.stroke();

Working fiddle

【讨论】:

    猜你喜欢
    • 2017-05-20
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    相关资源
    最近更新 更多