Maison > Questions et réponses > le corps du texte
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粉4278776762024-04-04 14:37:48
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.
.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 :
间隙
轮廓
taille pour couvrir l'espace laissé entre
Élément .row { gap: var(--col-gap); } .column { outline: var(--col-gap) solid gray; }
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%); }
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 :
display: none;
不会更改网格布局它完全取决于通过自定义变量 --col-width
设置的 .column
taille de l'élémentBien 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 <= count; i++) {
const column = document.createElement('div');
column.classList.add('column');
target.append(column);
}
}
//adds the square class to random .column elements in target
function addRandomSquares(target){
target.querySelectorAll('.column').forEach(column => {
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;
}