隨著父元素變小,減少填充大小
P粉807397973
P粉807397973 2024-04-03 17:37:05
0
1
354

我有一個在單元格中繪製正方形的網格。它具有行數和列數,然後繪製網格單元格並檢查每個單元格中是否應該有一個正方形(根據數組),並在需要時繪製一個正方形。 HTML 最終結果看起來像這樣:(假設我有 1 行和 3 個列,只有 2 個單元格應該有正方形)

.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>

行佔據螢幕的整個寬度,所有列之間的列大小應該相同,並根據螢幕上的列數進行更改(例如,如果我有5 列,它們都應該帶有寬度為100 像素,但如果我有1000 列,它們的寬度都應該是10 像素)。

我的問題是,在列大小中的某個斷點之後,填充和邊框半徑看起來很奇怪,我想在遇到該斷點時更改它們的值。 我無法使用 @container 查詢,因為仍然沒有完全支援。

如果它有幫助,我正在使用 vue 2。但我認為在這種情況下 CSS 解決方案會更好。

P粉807397973
P粉807397973

全部回覆(1)
P粉427877676

嘗試解決所描述的問題:

我製作了一個小演示,幫助我更好地探索實現這種場景的條件。

取得邊框:彈性盒項目上的折疊等效項

.row 元素仍然是Flexbox 容器,但它的Flex 項目沒有設定border,而是使用outline 設定進行樣式設定.

輪廓不佔用空間,當與另一個元素產生的輪廓碰撞時,它會「崩潰」。

因此,為了確保佈局不受樣式奇怪的影響,在嘗試展示 Flex 項目的邊框時,此演示僅依賴 2 個關鍵方面來渲染這些邊框:

  • 設定彈性項目之間的間隙
  • 設定輪廓大小,以覆蓋之間留下的間隙 元素
.row {
  gap: var(--col-gap);
}
.column {
  outline: var(--col-gap) solid gray;
}

使用 ::after 將內容加入到元素

另外,紅點被應用為具有 position:absolute::after 偽元素,再次確保沒有任何內容影響網格佈局:

.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 的“儀表板”,它保留在頁面頂部並允許您控制:

  • 列寬(px):您可以在此處設定寬度,根據可用的容器空間變更每行的列數
  • 每行列數:在這裡您可以設定每行的列數,根據可用的容器空間變更其寬度 寬度
  • 單元格之間的間隙(px):網格上單元格之間的間隙
  • 切換紅點可見性:將顯示/隱藏紅點,再次證明display: none; 不會更改網格佈局它完全取決於透過自訂變數--col-width 設定的.column 元素大小
  • 切換計數器可見性:將顯示/隱藏每個彈性項目頂部的計數器

到目前為止的結論:

儘管我們努力最大限度地減少干擾,並採取了僅根據單元格的固定大小#正確設置網格佈局所需的所有步驟,但仍然存在一些問題渲染問題,有時某些線條的邊框尺寸會出現常規的不匹配圖案。 我應該說,我只在筆記型電腦顯示器上遇到問題,而不是在桌上型電腦顯示器上,所以這是另一個因素。

我在演示中嘗試了不同的參數並處理數字,同時也考慮到了差距。良好且安全的佈局可以最大限度地減少潛在問題(例如,還可以提高邊框尺寸)。

使用 Flex 佈局我無法得到比這更進一步的結果。

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;
}
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板