Inhaltsverzeichnis
Aktivieren Sie zunächst Flags
Beginnen wir mit einigen Markups
Lassen Sie uns nun einige Stile anwenden
JavaScript -Fallback -Lösung
Einige geringfügige Verbesserungen
Eine realistischere Struktur
Machen Sie das erste Element das Netz überspannen
Handle Grid -Elemente mit variablen Seitenverhältnissen behandeln
Aber jedoch, aber ...
Wie ist Browser -Unterstützung?
Was ist mit der Situation ohne JavaScript?
Heim Web-Frontend CSS-Tutorial Eine leichte Mauerwerkslösung

Eine leichte Mauerwerkslösung

Apr 03, 2025 am 10:06 AM

Eine leichte Mauerwerkslösung

Im Mai habe ich erfahren, dass Firefox Mauerwerkslayout -Funktionalität in CSS -Gitter hinzugefügt hat. Mauerwerkslayout war etwas, das ich schon immer von Grund auf neu implementieren wollte, aber ich habe nie gewusst, wo ich anfangen soll. Also habe ich mir natürlich die Demo angesehen und dann hatte ich einen Blitz der Inspiration, als ich verstand, wie dieses neue CSS -Feature funktioniert.

Derzeit ist die Unterstützung auf Firefox beschränkt (und auch dort, nur wenn bestimmte Flags aktiviert sind), aber dies gibt mir immer noch einen Ausgangspunkt für eine JavaScript -Implementierung, mit der Browser, die derzeit fehlen, abdecken können.

Firefox implementiert das Mauerwerkslayout in CSS durch Einstellen grid-template-rows (wie im Beispiel gezeigt) oder grid-template-columns auf masonry Mauerwerkswert.

Mein Ansatz ist es, diese Funktion zu nutzen, um den Browser zu unterstützen. Lassen Sie uns sehen, wie dies mit einem bestimmten Fall eines Bildnetzes erreicht werden kann.

Aktivieren Sie zunächst Flags

Dazu besuchen wir about:config in Firefox und suchen Sie nach "Mauerwerk". Dadurch werden das Flag der layout.css.grid-template-masonry-value.enabled angezeigt, das wir aktivieren können, indem wir doppelklicken, um seinen Wert von false (dem Standardwert) auf true zu ändern.

Beginnen wir mit einigen Markups

Die HTML -Struktur lautet wie folgt:

<img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174364597525146.jpg" class="lazy" alt="Eine leichte Mauerwerkslösung">
Nach dem Login kopieren

Lassen Sie uns nun einige Stile anwenden

Zunächst stellen wir das oberste Element als CSS -Raster -Container fest. Als nächstes definieren wir die maximale Breite für das Bild, zum Beispiel 10em . Wir möchten auch, dass diese Bilder auf einen beliebigen Raum schrumpfen, der dem Raster -Inhaltsbox zur Verfügung steht. Wenn das Ansichtsfenster zu eng wird, um ein einzelnes 10em -Spaltenraster aufzunehmen, ist der Wert tatsächlich Min(10em, 100%) . Da reaktionsschnelles Design heutzutage sehr wichtig ist, adören wir automatisch so viele Spalten dieser Breite wie möglich an, anstatt eine feste Anzahl von Spalten zu verwenden:

 $ w: min (10em, 100%);

.Grid-masonry {
  Anzeige: Grid;
  Grid-Template-Säulen: Wiederholen (automatisch, $ w);

  > * {Breite: $ w; }
}
Nach dem Login kopieren

Beachten Sie, dass wir Min() anstelle von min() verwendet haben, um Sass -Konflikte zu vermeiden.

OK, das ist ein Netz!

Es ist jedoch kein sehr schönes Netz. Lassen Sie uns den Inhalt horizontal zentriert und dann die Gitterlücke und Füllung hinzufügen, beide gleich einem Abstandswert ( $s ). Wir haben auch einen Hintergrund für die einfachere Anzeige eingerichtet.

 $ s: .5em;

/* Mauerwerksnetzstil*/
.Grid-masonry {
  /* Gleich wie vorheriger Stil*/
  Justify-Content: Center;
  Raster-Lack: $ S;
  Polsterung: $ S;
}

/* Verschönerungsstil*/
html {Hintergrund: #555; }
Nach dem Login kopieren

Nach einer kleinen Verschönerung des Netzes haben wir uns dem Gitterprojekt (d. H. Das Bild) zum gleichen verwandelt. Wenden wir einen Filter an, damit er etwas gleichmäßiger aussieht und gleichzeitig einen zusätzlichen Stil mit leicht abgerundeten Ecken und Schatten hinzufügt.

 img {
  Border-Radius: 4px;
  Box-Shadow: 2px 2px 5px RGBA (#000, .7);
  Filter: Sepia (1);
}
Nach dem Login kopieren

Für Browser, die Mauerwerkslayouts unterstützen, müssen wir sie nur erklären:

 .Grid-masonry {
  /* Gleich wie vorheriger Stil*/
  Grid-Template-Reihen: massiv;
}
Nach dem Login kopieren

Während dies in den meisten Browsern nicht funktioniert, werden in Firefox mit den zuvor erklärten Flaggen die erwarteten Ergebnisse erzielt.

Aber was ist mit anderen Browsern? Das brauchen wir ...

JavaScript -Fallback -Lösung

Um den JavaScript-Code zu speichern, den der Browser ausführen muss, prüfen wir zunächst, ob es auf der Seite ein .grid--masonry -Element gibt und ob der Browser masonry von grid-template-rows verstanden und angewendet hat. Beachten Sie, dass dies ein allgemeiner Ansatz ist, vorausgesetzt, auf unserer Seite kann es mehrere solche Netze geben.

 lass grids = [... document.querySelectorAll ('. Grid-Masonry')];

if (grids.length && getComputedStyle (Grids [0]). GridTemplaterows! == 'Mauerwerk') {
  console.log ('oops, Mauerwerkslayout unterstützt nicht?');
} anders {
  console.log ('Zu gut, keine Operation erforderlich!');
}
Nach dem Login kopieren

Wenn die neue Mauerwerksfunktion nicht unterstützt wird, erhalten wir für jedes Mauerwerksnetz die Zeilenlücke und Maschen.

 lass grids = [... document.querySelectorAll ('. Grid-Masonry')];

if (grids.length && getComputedStyle (Grids [0]). GridTemplaterows! == 'Mauerwerk') {
  grids = grids.map (grid => ({{
    _el: Raster,
    Lücke: Parsefloat (GetComputedstyle (Grid) .Gridrowgap),
    Elemente: [... Grid.Childnodes] .Filter (c => c.nodetype === 1),
    NCOL: 0
  }));

  grids.foreach (grid => console.log (`grid item: $ {grid.items.length}; Grid Gap: $ {grid.gap} px`));
}
Nach dem Login kopieren

Beachten Sie, dass wir sicherstellen müssen, dass die untergeordneten Knoten Elementknoten sind (dies bedeutet, dass ihr nodeType 1 ist). Andernfalls können wir Textknoten haben, die aus Wagenrenditen im Projektarray bestehen.

Bevor wir fortfahren, müssen wir sicherstellen, dass die Seite geladen ist und sich die Elemente noch bewegen. Sobald wir uns mit diesem Problem befasst haben, nehmen wir jedes Netz und lesen seine aktuelle Anzahl von Spalten. Wenn sich dies von dem Wert unterscheidet, den wir bereits haben, aktualisieren wir den alten Wert und ordnen die Netzelemente neu an.

 if (grids.length && getComputedStyle (Grids [0]). GridTemplaterows! == 'Mauerwerk') {
  grids = grids.map (/* ist die gleiche wie vor*/);

  Funktionslayout () {
    grids.foreach (grid => {
      /* Die Spaltennummer der Größen-/geladenen Spaltennummer erhalten*/
      Sei ncol = getComputedStyle (grid._el) .gridTemPlateColumns.Split ('') .Length;

      if (grid.ncol! == ncol) {
        grid.ncol = ncol;
        console.log ('Raster -Gitterartikel neu ordnen');
      }
    });
  }

  AddEventListener ('Load', e => {
    Layout(); /* Anfängliche Last*/
    addEventListener ('Größe', Layout, Falsch);
  }, FALSCH);
}
Nach dem Login kopieren

Beachten Sie, dass das Aufrufen layout() -Funktion eine Operation ist, die wir durchführen müssen, wenn sowohl die anfängliche Belastung als auch die Änderung der Größe sind.

Um die Netzelemente neu zu ordnen, besteht der erste Schritt darin, den oberen Rand von allen Elementen zu entfernen (dies kann auf einen Wert ungleich Null eingestellt werden, um den Mauerwerkseffekt vor der Stromgrößenänderung zu erreichen).

Wenn das Ansichtsfenster eng genug ist und wir nur eine Spalte haben, dann sind wir fertig!

Andernfalls überspringen wir die ersten ncol -Elemente und schleifen den Rest durch. Für jeden berücksichtigten Artikel berechnen wir die Unterkanteposition des obigen Elements und seine aktuelle Position der oberen Kante. Auf diese Weise können wir berechnen, wie viel vertikale Bewegung benötigt wird, damit sich die Oberkante in einer Gitterlücke unterhalb der unteren Rand des obigen Projekts befindet.

 /* Wenn sich die Anzahl der Spalten geändert hat*/
if (grid.ncol! == ncol) {
  /* Anzahl der aktualisierten Spalten*//
  grid.ncol = ncol;

  /* Erstpositionierung wiederherstellen, kein Rand*/
  Grid.Items.foreach (c => C.Style.RemoveProperty ('Margin-Top'));

  /* Wenn wir mehr als eine Spalte haben*/
  if (grid.ncol> 1) {
    grid.items.lice (ncol) .foreach ((c, i) => {
      Sei prev_fin = grid.items [i] .GetBoundingClientRect (). Unten, unten des obigen Projekts* /
          Curr_ini = C.GetBoundingClientRect (). Top; /* Oberkante des aktuellen Projekts*/

      C.Style.Margintop = `$ {prev_fin grid.gap - curr_ini} px`;
    });
  }
}
Nach dem Login kopieren

Jetzt haben wir eine funktionierende Cross-Browser-Lösung!

Einige geringfügige Verbesserungen

Eine realistischere Struktur

In der realen Welt wickeln wir jedes Bild mit größerer Wahrscheinlichkeit in einen Link zu seinem Bild in voller Größe ein, damit das große Bild in der Lichtkiste geöffnet werden kann (oder wir navigieren als Fallback).

<a href="https://www.php.cn/link/849c1f472f609bb4a3bacafef177f541">
  <img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174364597550777.jpg" class="lazy" alt="Eine leichte Mauerwerkslösung">
</a>
Nach dem Login kopieren

Dies bedeutet, dass wir auch das CSS ein wenig ändern müssen. Obwohl wir die Breite der Netzelemente nicht mehr explizit festlegen müssen - weil sie jetzt Links sind - müssen wir align-self: start , da sie im Gegensatz zu Bildern standardmäßig die gesamte Zeilenhöhe abdecken, die unseren Algorithmus stört.

 .Grid-masonry> * {Align-Self: Start; }

img {
  Anzeige: Block; /* Vermeiden Sie seltsamen zusätzlichen Platz unten*///
  Breite: 100%;
  /* Gleich wie vorheriger Stil*/
}
Nach dem Login kopieren

Machen Sie das erste Element das Netz überspannen

Wir können auch das erste Projekt horizontal über das gesamte Netz umfassen (was bedeutet, dass wir wahrscheinlich auch seine Höhe begrenzen und sicherstellen sollten, dass das Bild nicht überflutet oder verformt):

 .Grid-masonry>: Erstkind {
  Grid -Säule: 1 / -1;
  maximalhöhe: 29 VH;
}

img {
  Max-Höhe: Erbe;
  Objekt-Fit: Deckung;
  /* Gleich wie vorheriger Stil*/
}
Nach dem Login kopieren

Wir müssen auch einen weiteren Filter hinzufügen, wenn wir die Liste der Netzelemente erhalten, um diesen gestreckten Element auszuschließen:

 grids = grids.map (grid => ({{
  _el: Raster,
  Lücke: Parsefloat (GetComputedstyle (Grid) .Gridrowgap),
  Elemente: [... Grid.Childnodes] .Filter (c =>
    c.nodetype === 1 &&
     GetComputedStyle (C) .GridColumnend! == -1
  ),
  NCOL: 0
}));
Nach dem Login kopieren

Handle Grid -Elemente mit variablen Seitenverhältnissen behandeln

Angenommen, wir möchten diese Lösung für Zwecke wie Bloggen verwenden. Wir behalten genau die gleichen JS und nahezu identischen Mauerwerks-spezifischen CSS-wir ändern nur die maximale Breite der Säule und entfernen die max-height -Grenze für das erste Element.

Wie aus der folgenden Demonstration hervorgeht, funktioniert unsere Lösung in diesem Fall perfekt und wir haben ein Blog -Post -Raster:

Sie können das Ansichtsfenster auch ändern, um zu sehen, wie es in diesem Fall funktioniert.

Wenn wir jedoch möchten, dass die Spaltenbreite beispielsweise eine gewisse Flexibilität hat:

 $ w: minmax (min (20em, 100%), 1fr);
Nach dem Login kopieren

Dann werden wir bei der Größe auf Probleme stoßen:

Die Kombination der Änderung der Breite der Netzelemente und die Tatsache, dass der Textinhalt jedes Elements unterschiedlich ist, bedeutet, dass wir, wenn ein bestimmter Schwellenwert überschritten wird, eine unterschiedliche Anzahl von Textzeilen für Gitterelemente erhalten (und somit die Höhe ändern), andere Elemente jedoch nicht. Wenn sich die Anzahl der Spalten nicht geändert hat, ist der vertikale Offset nicht neu berechnet und wir haben überlappende oder größere Lücken.

Um dieses Problem zu lösen, müssen wir den Offset neu berechnen, wenn sich die aktuelle Gitterhöhe von mindestens einem Element ändert. Dies bedeutet, dass wir auch testen müssen, ob es im aktuellen Netz mehr als Nullartikel gibt, die ihre Höhe geändert haben. Dann müssen wir diesen Wert am Ende if -Blocks zurücksetzen, damit wir die Elemente beim nächsten Mal nicht unnötig neu ordnen müssen.

 if (grid.ncol! == ncol || grid.mod) {
  /* Wie früher*/
  grid.mod = 0;
}
Nach dem Login kopieren

OK, aber wie ändern wir diesen grid.mod ? Meine erste Idee ist es, ResizeObserver zu verwenden:

 if (grids.length && getComputedStyle (Grids [0]). GridTemplaterows! == 'Mauerwerk') {
  Sei O = New ReiseBerver (Einträge => {
    Einträge.foreach (Eintrag => {
      grids.find (grid => grid._el === Eintrag.target.Parentelement) .mod = 1;
    });
  });

  /* Wie früher*/

  AddEventListener ('Load', e => {
    /* Wie früher*/
    grids.foreach (grid => {grid.items.foreach (c => o.observe (c));});
  }, FALSCH);
}
Nach dem Login kopieren

Dies ermöglicht es, die Netzelemente bei Bedarf neu zu ordnen, auch wenn sich die Anzahl der Netzspalten nicht geändert hat. Es macht es aber auch bedeutungslos, auch if die Bedingungen nicht verfügbar sind!

Dies liegt daran, dass das grid.mod auf 1 wechselt, wenn sich die Höhe oder Breite von mindestens einem Element ändert. Die Höhe des Projekts ändert sich aufgrund des Textausfalls, der durch Veränderung der Breite verursacht wird. Die Veränderung der Breite wird jedoch jedes Mal stattfinden, wenn wir die Ansichtsfenstergröße anpassen, und sie löst nicht unbedingt die Höhenänderung aus.

Aus diesem Grund habe ich mich entschlossen, frühere Projekthöhen zu speichern und zu prüfen, ob sie sich bei der Änderung geändert haben, um festzustellen, ob grid.mod bei 0 bleibt:

 Funktionslayout () {
  grids.foreach (grid => {
    grid.items.foreach (c => {
      let new_h = c.GetBoundingClientRect (). Höhe;

      if (new_h! == c.dataset.h) {
        C.Dataset.h = new_h;
        grid.mod;
      }
    });

    /* Wie früher*/
  });
}
Nach dem Login kopieren

Das war's! Jetzt haben wir eine schöne leichte Lösung. Der komprimierte JavaScript beträgt weniger als 800 Bytes, während strenge Stile im Zusammenhang mit Mauerwerk weniger als 300 Bytes beträgt.

Aber jedoch, aber ...

Wie ist Browser -Unterstützung?

Nun, @supports bietet zufällig eine bessere Browser-Unterstützung als jede neuere CSS-Funktion, die hier verwendet wird, sodass wir das gute Zeug einsetzen und ein grundlegendes nicht masonriges Netz für nicht unterstützte Browser bereitstellen können. Diese Version ist rückwärtskompatibel für IE9.

Es mag anders aussehen, aber es sieht gut aus und hat eine perfekte Funktion. Die Unterstützung eines Browsers bedeutet nicht, alle visuellen Effekte dafür zu kopieren. Dies bedeutet, dass die Seite funktioniert und nicht beschädigt oder hässlich aussieht.

Was ist mit der Situation ohne JavaScript?

Nun, wir können nur ausgefallene Stile anwenden, wenn das Root -Element js -Klasse hat, die wir über JavaScript hinzugefügt haben! Andernfalls erhalten wir für alle Gegenstände ein Basisnetz von gleicher Größe.

Das obige ist der detaillierte Inhalt vonEine leichte Mauerwerkslösung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

<🎜>: Bubble Gum Simulator Infinity - So erhalten und verwenden Sie Royal Keys
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusionssystem, erklärt
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Flüstern des Hexenbaum
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Java-Tutorial
1664
14
PHP-Tutorial
1269
29
C#-Tutorial
1249
24
Ein Beweis für das Konzept, um Sass schneller zu machen Ein Beweis für das Konzept, um Sass schneller zu machen Apr 16, 2025 am 10:38 AM

Zu Beginn eines neuen Projekts erfolgt die SASS -Zusammenstellung im Blinzeln eines Auges. Dies fühlt sich gut an, besonders wenn es mit Browsersync kombiniert ist, das nachlädt

Ein Vergleich statischer Formanbieter Ein Vergleich statischer Formanbieter Apr 16, 2025 am 11:20 AM

Versuchen wir, hier einen Begriff zu prägen: "Statischer Formanbieter". Sie bringen Ihre HTML

Wöchentliche Plattformnachrichten: HTML -Ladeattribut, die Haupt -ARIA -Spezifikationen und Wechsel von Iframe zu Shadow Dom Wöchentliche Plattformnachrichten: HTML -Ladeattribut, die Haupt -ARIA -Spezifikationen und Wechsel von Iframe zu Shadow Dom Apr 17, 2025 am 10:55 AM

In der Zusammenfassung der Plattformnachrichten in dieser Woche stellt Chrome ein neues Attribut für das Laden, Zugänglichkeitspezifikationen für Webentwickler und die BBC -Bewegungen ein

Der Deal mit dem Abschnittselement Der Deal mit dem Abschnittselement Apr 12, 2025 am 11:39 AM

Zwei Artikel veröffentlichten genau den selben Tag:

Multi-Daumen-Schieberegler: Allgemeiner Fall Multi-Daumen-Schieberegler: Allgemeiner Fall Apr 12, 2025 am 10:52 AM

In dem ersten Teil dieser zweiteiligen Serie werden beschrieben, wie wir einen Zwei-Daumen-Schieberegler erhalten können. Jetzt sehen wir uns einen allgemeinen Multi-Thumb-Fall an, aber mit einem anderen und

Einige praktisch mit dem HTML-Dialogelement Einige praktisch mit dem HTML-Dialogelement Apr 16, 2025 am 11:33 AM

Ich schaue mir das HTML -Element zum ersten Mal an. Ich habe es für eine Weile dessen bewusst, aber Haven &#039; Es wurde es noch nicht für einen Dreh genommen. Es hat einige ziemlich cool und

Wie wir Google -Schriftarten getaggt und Goofonts.com erstellt haben Wie wir Google -Schriftarten getaggt und Goofonts.com erstellt haben Apr 12, 2025 pm 12:02 PM

Goofonts ist ein Nebenprojekt, das von einer Entwicklerin und einem Designer-Ehemann signiert wurde, beide große Fans der Typografie. Wir haben Google markiert

Es ist alles in der Kopf Es ist alles in der Kopf Apr 15, 2025 am 11:01 AM

Der Dokumentkopf ist vielleicht nicht der glamouröseste Teil einer Website, aber was darauf einfließt

See all articles