À mesure que l'élément parent devient plus petit, réduisez la taille du remplissage
P粉807397973
P粉807397973 2024-04-03 17:37:05
0
1
387

J'ai une grille qui dessine des carrés dans les cellules. Il a le nombre de lignes et de colonnes, puis dessine les cellules de la grille et vérifie s'il doit y avoir un carré dans chaque cellule (selon le tableau) et dessine un carré si nécessaire. Le résultat final HTML ressemble à ceci : (en supposant que j'ai 1 ligne et 3 colonnes, seules 2 cellules devraient avoir des carrés)

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

Les lignes occupent toute la largeur de l'écran et les tailles des colonnes doivent être les mêmes entre toutes les colonnes et changer en fonction du nombre de colonnes à l'écran (par exemple, si j'ai 5 colonnes, elles doivent toutes avoir une largeur de 100). pixels mais si j'ai 1000 colonnes, elles devraient toutes avoir une largeur de 10 pixels).

Mon problème est que le remplissage et le rayon de bordure semblent bizarres après un certain point d'arrêt dans la taille de la colonne et je souhaite modifier leurs valeurs lorsque j'atteins ce point d'arrêt. Je ne peux pas utiliser les requêtes @container car elles ne sont toujours pas entièrement prises en charge.

Si cela peut aider, j'utilise vue 2. Mais je pense qu'une solution CSS serait meilleure dans ce cas.

P粉807397973
P粉807397973

répondre à tous(1)
P粉427877676

Essayez de résoudre le problème décrit :

J'ai fait une petite démo pour m'aider à mieux explorer ce qu'il faut pour réaliser ce scénario.

Obtenir la bordure : réduire l'équivalent sur l'élément flexbox

.row 元素仍然是一个 Flexbox 容器,但它的 Flex 项目没有设置 border,而是使用 outline Paramètres de style.

Le contour ne prend pas de place et "s'effondrera" en cas de collision avec le contour généré par un autre élément.

Ainsi, pour garantir que la mise en page n'est pas affectée par des bizarreries de style, lorsque vous essayez d'afficher les bordures d'un élément Flex, cette démo s'appuie sur seulement 2 aspects clés pour restituer ces bordures :

  • Définissez les éléments flexibles entre 间隙
  • Définissez la 轮廓 taille pour couvrir l'espace laissé entre Élément
.row {
  gap: var(--col-gap);
}
.column {
  outline: var(--col-gap) solid gray;
}

Utilisez ::after pour ajouter du contenu aux éléments

De plus, le point rouge est appliqué avec un pseudo-élément position:absolute::after, garantissant encore une fois que rien n'affecte la disposition de la grille :

.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%); 
}

Tableau de bord - Explorer les options

A partir de là, j'ai ajouté un "tableau de bord" avec position:fixed qui reste en haut de la page et permet de contrôler :

  • Largeur de colonne (px)  : Ici, vous pouvez définir la largeur, modifier le nombre de colonnes par ligne en fonction de l'espace du conteneur disponible
  • Nombre de colonnes par ligne : Ici, vous pouvez définir le nombre de colonnes par ligne, en modifiant sa largeur en fonction de l'espace disponible du conteneur Largeur
  • Espace entre les cellules (px) : Espace entre les cellules de la grille
  • Basculer la visibilité du point rouge : affichera/masquera le point rouge, démontrant à nouveau la display: none; 不会更改网格布局它完全取决于通过自定义变量 --col-width 设置的 .column taille de l'élément
  • Toggle Counter Visibility : affichera/masquera le compteur au-dessus de chaque élément flexible

Conclusion jusqu'à présent :

Bien que nous nous efforcions de minimiser les distractions et de prendre toutes les mesures nécessaires pour configurer correctement la disposition de la grille en fonction uniquement de la taille fixe des cellules, il reste encore quelques problèmes de rendu et parfois de taille de bordure de certaines lignes. un schéma de disparités se produit. Je dois dire que je n'ai des problèmes qu'avec les écrans d'ordinateurs portables, pas avec les moniteurs de bureau , c'est donc un autre facteur.

J'ai essayé différents paramètres et calculé les chiffres dans la démo, en tenant également compte des lacunes. Une disposition efficace et sûre peut minimiser les problèmes potentiels (par exemple, elle peut également augmenter la taille des bordures).

Je ne pouvais pas aller plus loin avec la mise en page 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;
}
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal