Ändern Sie die Spaltengröße im CSS-Grid-Layout dynamisch mit der Maus

Lesezeit: 6 Minuten

Benutzer-Avatar
ccpizza

Ich versuche, die Größe von CSS-Grid-Layout-Boxen dynamisch zu ändern, indem ich die Spaltentrenner (oder die Größe von Platzhaltern) mit der Maus ziehe.

ich setze resize: horizontal; auf der nav Element, dessen Größe geändert werden soll, und seine Größe wird geändert, wenn ich den kleinen Ziehgriff zur Größenänderung in der unteren rechten Ecke des Elements ziehe, aber die Breite der benachbarten Spalte wird nicht automatisch angepasst, was zu einer Überlappung führt. Hier ist ein kaputter Codestift.

HTML:

<main>
 <nav>#1</nav>
 <header>#2</header>
 <section>#3</section>
</main>

CSS:

main {
    display: grid;
    border: 3px dotted red;
    grid-gap: 3px;
    grid-template-columns: 200px 1fr;
    grid-template-rows: 100px 1fr;
    height: 100%;
}

nav {
    grid-column: 1;
    grid-row: 1;
    grid-row: 1 / span 2;
    resize: horizontal;
    overflow: scroll;
    border: 3px dotted blue;
}

Ich hatte erwartet, dass die CSS-Grid-Engine diesen Fall automatisch behandelt, aber anscheinend tut sie das nicht.

Ich habe mit experimentiert jquery-ui veränderbar aber es scheint nicht gut mit CSS-Grids zu funktionieren.

Ich untersuche, wie man es mit jquery macht, indem man das Grid-Attribut setzt grid-template-columns/rows: auf einen dynamischen Wert, aber es ist nicht klar, wie die Ereignisse abgefangen werden sollen, die durch die Größenänderung des Elements über das Resize-Handle ausgelöst werden. Die jquery Größe ändern Ereignis wird nur auf dem ausgelöst window Objekt und nicht auf Dom-Elementen.

Was könnte eine Möglichkeit sein, dies zu tun, ohne Mausereignisse auf niedriger Ebene wie dragstart/dragend behandeln zu müssen?

  • Tolle Frage. Ich denke, dass anpassbare Rasterbereiche eine wichtige Sache sein werden, sobald sich diese Technologie wirklich verbreitet. Warum die Größe der zweiten Spalte nicht geändert wird, wenn Sie die erste Spalte herausziehen, liegt meiner Meinung nach daran, dass diese Aktion das Dokument nicht neu umfließt. Hier ist eine vollständigere Erklärung: stackoverflow.com/q/37406353/3597276

    – Michael Benjamin

    4. September 2017 um 22:20 Uhr


  • @dekel: danke! werde versuchen zu sehen, ob es an ein CSS-Grid-Layout angepasst werden kann; Andernfalls muss möglicherweise auf die Verwendung von Floats umgestellt werden.

    – ccpizza

    4. September 2017 um 22:32 Uhr

Was Sie erreichen möchten, ist nur mit CSS möglich. Ich habe dein Beispiel modifiziert. Die wichtigsten Takeaways sind diese:

  1. Versuchen Sie vor allem, keine Rohinhalte in Ihre semantischen Layout-Tags einzufügen. Verwenden Sie statt text- und br-Tags Header-, Paragraph- und List-Tags. Dadurch wird Ihr Code sowohl leichter lesbar als auch verständlicher. Viele Ihrer Probleme sind darauf zurückzuführen, wie Reflow in Grid-Bereichen gehandhabt wird.
  2. Verwenden Sie Grid-Template, um Ihr Layout zu vereinfachen, da es später das Umfließen von Haltepunkten erleichtert.
  3. Überlauf verwenden: auto; zusammen mit der Angabe der Größenänderung: vertikal/horizontal. Ohne das Festlegen von Überlauf schlägt die Größenänderung fehl.
  4. Verwenden Sie minimale/maximale Breiten-/Höhenwerte, um Grenzen für die Größenänderung zu erstellen.
body {
    margin: 10px;
    height: 100%;
}

main {
    display: grid;
    border: 3px dotted red;
    padding: 3px;
    grid-gap: 3px;
    
    grid-template: 
    "nav head" min-content
    "nav main" 1fr
        / min-content 1fr;
}

nav {
    grid-area: nav;
    border: 3px dotted blue;
    overflow: auto;
    resize: horizontal;
    
    min-width: 120px;
    max-width: 50vw;
}

header {
    grid-area: head;
    border: 3px dotted orange;
    overflow: auto;
    resize: vertical;
    
    min-height: min-content;
    max-height: 200px;
}

section {
    grid-area: main;
    border: 3px dotted gray;
}
<main>
  <nav>
    <ul>
      <li>Nav Item</li>
      <li>Nav Item</li>
      <li>Nav Item</li>
      <li>Nav Item</li>
      <li>Nav Item</li>
      <li>Nav Item</li>
    </ul>
  </nav>

  <header>
    <h1>Header Title</h1>
    <small>Header Subtitle</small>
  </header>

  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  </section>
</main>

  • Ist es möglich, über den gesamten Rand zu ziehen, anstatt nur über die untere rechte Ecke?

    – Alan Tygel

    9. August 2019 um 16:47 Uhr

  • Ja: $( “.selector” ).resizable({handles: “e, w”});

    – Alan Tygel

    9. August 2019 um 16:56 Uhr

  • Vielen Dank, Überlauf: ‘auto’, Größenänderung: ‘horizontal’ hat bei mir funktioniert

    – DenisDaniel707

    3. März 2021 um 13:42 Uhr

  • @AlanTygel Da es sich bei dieser Antwort um reines CSS handelt, ist es frustrierend, dass die Lösung, die Sie für das Drag-the-Border-Problem gefunden haben, jQuery beinhaltet. Ich suche immer noch nach dem richtigen Weg, dies zu tun (Rasterlayout + Handler zur Größenänderung des vollständigen Rahmens) mit minimalem oder keinem zusätzlichen Markup und möglichst ohne Abhängigkeit …

    – Nicolas Le Thierry d’Ennequin

    14. März 2021 um 11:27 Uhr

  • Es ist 2022 und CSS bietet keine Syntax zur Größenänderung von Rändern wie diese: border-left: 2px solid #ccc resizable aber wir können ein Element im 3D-Raum drehen und sogar die Perspektive ändern. So erstaunlich sind die Dinge im Internet.

    – poya

    Vor 2 Tagen

Benutzer-Avatar
ccpizza

Die Lösung ist nicht Verwenden Sie explizite feste Spaltengröße (grid-template-columns: 200px 1fr;), sondern verwenden Sie stattdessen relative Spaltengrößen wie z grid-template-columns: 0.2fr 1fr; — dann übernimmt die Raster-CSS-Engine die Größenänderung benachbarter Felder. Als Nächstes fügen Sie verschachtelte Divs in die Gitterboxen ein, setzen ihre Mindesthöhe/Breite auf 100 % und machen sie in der Größe veränderbar über jqueryui veränderbar.

Das Feste jsfiddle.

/* Javscript */

$('.left_inner').resizable();
$('.right_top_inner').resizable();
$('.right_bottom_inner').resizable();
/* CSS */

	.grid {
		display: grid;
		grid-template-columns: 0.2fr 1fr;
		grid-template-rows: 1fr 4fr;
        grid-gap: 3px;
		position: relative;
	}

	.left {
		grid-row: 1 / span 2;
	}

	.right_top {
		grid-column: 2;
		grid-row: 1;
	}

	.right_bottom {
		grid-column: 2;
		grid-row: 2;
	}

	.left_inner {
		background-color: #fedcd2;
		padding: 0;
		width: 100%;
		min-width: 100%;
		height: 100%;
		min-height: 100%;
		text-align: center;
	}

	.right_top_inner {
		background-color: #f9cf00;
		padding: 0;
		width: 100%;
		min-width: 100%;
		height: 100%;
		min-height: 100%;
		text-align: center;
	}

	.right_bottom_inner {
		background-color: #f8eee7;
		padding: 0;
		width: 100%;
		min-width: 100%;
		height: 100%;
		min-height: 100%;
		text-align: center;
	}
<!-- HTML -->

<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/css/smoothness/jquery-ui-1.10.0.custom.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/jquery-ui.js"></script>

	<main class="grid">
	 <aside class="left">
	  <div class="left_inner">
		drag the bottom right handle to resize
	  </div>
	 </aside>
	 <section class="right_top">
	  <div class="right_top_inner">right_top_inner</div>
	 </section>
	 <section class="right_bottom">
	  <div class="right_bottom_inner">right_bottom_inner</div>
	 </section>
	</main>

❗️ Während dies im einfachsten möglichen Szenario funktioniert, wird es in einem realen Anwendungsfall problematisch. Ich habe es versucht jquery-ui-Layout was etwas besser funktionierte (hier ist eine Demo), aber die Lib ist veraltet und hat Probleme mit Frames, also habe ich mitgemacht eckig geteilte Scheibe (basierend auf Winkel 1), das gut funktioniert und kleiner ist. (Update: Es scheint, dass das Projekt derzeit aufgegeben wird, also wahrscheinlich nicht die beste Wahl)

1225760cookie-checkÄndern Sie die Spaltengröße im CSS-Grid-Layout dynamisch mit der Maus

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy