Ich habe ein Raster, das Quadrate in Zellen zeichnet. Es ermittelt die Anzahl der Zeilen und Spalten, zeichnet dann die Gitterzellen und prüft, ob in jeder Zelle ein Quadrat vorhanden sein sollte (gem?? der Anordnung), und zeichnet bei Bedarf ein Quadrat. Das HTML-Endergebnis sieht so aus: (Angenommen, ich habe 1 Zeile und 3 Spalten, nur 2 Zellen sollten Quadrate haben)
.row { display: flex; flex-wrap: wrap; flex: 10000 1 0%; } .column { display: flex; flex-wrap: wrap; max-width: 100px; min-width: 10px; padding: 4px; border: 1px solid grey; } .square { background-color: red; width: 100%; aspect-ratio: 1/1; border-radius: 5px; }
<div class="row"> <div class="column"> <div class="square"></div> </div> <div class="column"> <div class="square"></div> </div> <div class="column"></div> </div>
Die Zeilen nehmen die gesamte Breite des Bildschirms ein und die Spaltengr??en sollten zwischen allen Spalten gleich sein und sich je nach Anzahl der Spalten auf dem Bildschirm ?ndern (wenn ich beispielsweise 5 Spalten habe, sollten sie alle eine Breite von 100 haben). Pixel, aber wenn ich 1000 Spalten habe, sollten sie alle 10 Pixel breit sein).
Mein Problem ist, dass der Abstand und der Randradius nach einem bestimmten Haltepunkt in der Spaltengr??e seltsam aussehen und ich ihre Werte ?ndern m?chte, wenn ich diesen Haltepunkt erreiche. Ich kann keine @container-Abfragen verwenden, da diese noch nicht vollst?ndig unterstützt werden.
Wenn es hilft, verwende ich Vue 2. Aber ich denke, eine CSS-L?sung w?re in diesem Fall besser.
嘗試解決所描述的問題:
我制作了一個小演示,幫助我更好地探索實現(xiàn)這種場景的條件。
.row
元素仍然是一個 Flexbox 容器,但它的 Flex 項目沒有設(shè)置 border
,而是使用 outline
設(shè)置進行樣式設(shè)置.
輪廓不占用空間,當與另一個元素生成的輪廓碰撞時,它會“崩潰”。
因此,為了確保布局不受樣式奇怪的影響,在嘗試展示 Flex 項目的邊框時,此演示僅依賴于 2 個關(guān)鍵方面來渲染這些邊框:
間隙
輪廓
大小,以覆蓋之間留下的間隙
元素.row { gap: var(--col-gap); } .column { outline: var(--col-gap) solid gray; }
另外,紅點被應(yīng)用為具有 position:absolute
的 ::after
偽元素,再次確保沒有任何內(nèi)容影響網(wǎng)格布局:
.column.square::after { position: absolute; content: ''; background-color: red; width: 50%; aspect-ratio: 1/1; border-radius: 100%; top: 50%; left: 50%; transform: translate(-50%, -50%); }
從那里開始,我添加了一個帶有 position:fixed
的“儀表板”,它保留在頁面頂部并允許您控制:
display: none;
不會更改網(wǎng)格布局它完全取決于通過自定義變量 --col-width
設(shè)置的 .column
元素大小盡管我們努力最大限度地減少干擾,并采取了僅根據(jù)單元格的固定大小正確設(shè)置網(wǎng)格布局所需的所有步驟,但仍然存在一些問題渲染問題,有時某些線條的邊框尺寸會出現(xiàn)常規(guī)的不匹配圖案。 我應(yīng)該說,我只在筆記本電腦顯示屏上遇到問題,而不是在臺式機顯示器上,所以這是另一個因素。
我在演示中嘗試了不同的參數(shù)并處理數(shù)字,同時也考慮到了差距。良好且安全的布局可以最大限度地減少潛在問題(例如,還可以提高邊框尺寸)。
使用 Flex 布局我無法得到比這更進一步的結(jié)果。
const container = document.getElementById('container');
//draws the board
emptyElementAndFillWithColumns(container, 100);
//sets some columns randomly as .square
addRandomSquares(container);
//initializes the dashboard with the value coming from the css custom props
let columnsGap = parseInt(getCssCustomProp('col-gap'));
let columnsWidth = parseInt(getCssCustomProp('col-width'));
document.getElementById('gap').value = columnsGap;
document.getElementById('width').value = columnsWidth;
document.getElementById('width').dispatchEvent(new Event('change'));
document.getElementById('cols').value = Math.trunc(container.offsetWidth / (columnsWidth+columnsGap));
//input#width change event handler
document.getElementById('width')
.addEventListener('change', event => {
const width = parseInt(event.target.value);
const newCols = Math.trunc(container.offsetWidth / (width+columnsGap));
setCssCustomProp(container, 'col-width', `${width}px`);
document.getElementById('cols').value = newCols;
});
//input#cols change event handler
document.getElementById('cols')
.addEventListener('change', event => {
const cols = parseInt(event.target.value);
const newWidth = Math.trunc(container.offsetWidth / cols) - columnsGap;
setCssCustomProp(container, 'col-width', `${newWidth}px`);
document.getElementById('width').value = newWidth;
});
//input#gap change event handler
document.getElementById('gap')
.addEventListener('change', event => {
const gap = parseInt(event.target.value);
setCssCustomProp(container, 'col-gap', `${gap}px`);
columnsGap = gap;
});
//input#toggle-dots change event handler
document.getElementById('toggle-dots')
.addEventListener('change', event => {
container.classList.toggle('hide-dots');
});
//input#toggle-counters change event handler
document.getElementById('toggle-counters')
.addEventListener('change', event => {
container.classList.toggle('hide-counters');
});
//sets the --propName custom property at the style of target
function setCssCustomProp(target, propName, value){
target.style.setProperty(`--${propName}`, `${value}`);
}
//gets the --propName custom property value from the rule set on :root
function getCssCustomProp(propName){
const propValue =
getComputedStyle(document.documentElement).getPropertyValue(`--${propName}`);
return propValue;
}
//resets the container and appends a count number of columns
function emptyElementAndFillWithColumns(target, count){
for (i = 0; i {
if (Math.random() >= 0.5)
column.classList.add('square');
})
}
:root {
--col-width: 100px;
--col-gap: 1px;
}
*,
*::after,
*::before {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: sans-serif;
}
.row {
display: flex;
flex-wrap: wrap;
gap: var(--col-gap);
counter-reset: itemnr;
}
.column {
position: relative;
display: flex;
flex-wrap: wrap;
width: var(--col-width);
height: var(--col-width);
padding: 4px;
outline: var(--col-gap) solid gray;
}
.column.square::after {
position: absolute;
content: '';
background-color: red;
width: 50%;
aspect-ratio: 1/1;
border-radius: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.dashboard {
position: fixed;
right: 1rem;
top: 2rem;
border: solid darkgray;
padding: 1em;
z-index: 100;
background: gray;
color: white;
font-weight: 600;
font-size: 1.2rem;
opacity: .9;
}
.dashboard > *{
display: grid;
grid-template-columns: 1fr auto;
width: 100%;
gap: 1em;
}
.dashboard label{
}
.dashboard input[type="number"] {
width: 5em;
cursor: pointer;
}
.dashboard input[type="checkbox"] {
width: 1rem;
line-height: 1rem;
cursor: pointer;
}
#container.hide-dots .square::after{
display: none;
}
#container.hide-counters .column::before{
display: none;
}
small{
grid-column: 1 / -1;
font-size:.8rem;
text-align: center;
width: 100%;
margin-bottom: 1rem;
}
.column::before{
position: absolute;
counter-increment: itemnr;
content: counter(itemnr);
font-size: .8rem;
z-index: 10;
font-weight: 600;
}