Ich habe ein Skript (mit Hilfe eines Benutzers hier) codiert, mit dem ich ein ausgewähltes Div erweitern und die anderen Divs entsprechend verhalten kann, indem ich es gleichmäßig strecke, um es an den verbleibenden Platz anzupassen (mit Ausnahme des ersten, dessen Breite festgelegt ist).
Und hier ist ein Bild von dem, was ich erreichen möchte:
Dafür benutze ich Flex und Übergänge.
Es funktioniert gut, aber das jQuery-Skript gibt einen Dehnungswert von "400%" an (der sich hervorragend zum Testen eignet).
Jetzt möchte ich, dass das ausgewählte div erweitert / verkleinert wird, um genau zum Inhalt zu passen, anstatt zum festen Wert "400%".
Ich habe keine Ahnung, wie ich das machen könnte.
Ist es möglich ?
Ich habe versucht, das div zu klonen, es an den Inhalt anzupassen, seinen Wert abzurufen und diesen Wert dann für den Übergang zu verwenden, ABER dies bedeutet, dass ich eine anfängliche Breite in Prozent, aber einen Zielwert in Pixel habe. Das geht nicht
Und wenn ich den Pixelwert in Prozent umrechne, passt das Ergebnis aus irgendeinem Grund nicht genau zum Inhalt.
In allen Fällen scheint dies ein etwas komplizierter Weg zu sein, um das zu erreichen, was ich sowieso will.
Gibt es keine Flex-Eigenschaft, die geändert werden könnte, um dem Inhalt eines ausgewählten Divs zu entsprechen?
Hier ist der Code ( bearbeitet / vereinfacht, da zum besseren Lesen ):
var expanded = '';
$(document).on("click", ".div:not(:first-child)", function(e) {
var thisInd =$(this).index();
if(expanded != thisInd) {
//fit clicked fluid div to its content and reset the other fluid divs
$(this).css("width", "400%");
$('.div').not(':first').not(this).css("width", "100%");
expanded = thisInd;
} else {
//reset all fluid divs
$('.div').not(':first').css("width", "100%");
expanded = '';
}
});
.wrapper {
overflow: hidden;
width: 100%;
margin-top: 20px;
border: 1px solid black;
display: flex;
justify-content: flex-start;
}
.div {
overflow: hidden;
white-space: nowrap;
border-right: 1px solid black;
text-align:center;
}
.div:first-child {
min-width: 36px;
background: #999;
}
.div:not(:first-child) {
width: 100%;
transition: width 1s;
}
.div:not(:first-child) span {
background: #ddd;
}
.div:last-child {
border-right: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Click on the div you want to fit/reset (except the first div)
<div class="wrapper">
<div class="div"><span>Fixed</span></div>
<div class="div"><span>Fluid (long long long long long text)</span></div>
<div class="div"><span>Fluid</span></div>
<div class="div"><span>Fluid</span></div>
</div>
Hier ist die jsfiddle:
https://jsfiddle.net/zajsLrxp/1/
BEARBEITEN: Hier ist meine Arbeitslösung mit Hilfe von Ihnen allen (Größen, die beim Ändern der Fenstergröße aktualisiert wurden + Anzahl der Divs und dynamisch berechnete Breite der ersten Spalte):
var tableWidth;
var expanded = '';
var fixedDivWidth = 0;
var flexPercentage = 100/($('.column').length-1);
$(document).ready(function() {
// Set width of first fixed column
$('.column:first-child .cell .fit').each(function() {
var tempFixedDivWidth = $(this)[0].getBoundingClientRect().width;
if( tempFixedDivWidth > fixedDivWidth ){fixedDivWidth = tempFixedDivWidth;}
});
$('.column:first-child' ).css('min-width',fixedDivWidth+'px')
//Reset all fluid columns
$('.column').not(':first').css('flex','1 1 '+flexPercentage+'%')
})
$(window).resize( function() {
//Reset all fluid columns
$('.column').not(':first').css('flex','1 1 '+flexPercentage+'%')
expanded = '';
})
$(document).on("click", ".column:not(:first-child)", function(e) {
var thisInd =$(this).index();
// if first click on a fluid column
if(expanded != thisInd)
{
var fitDivWidth=0;
// Set width of selected fluid column
$(this).find('.fit').each(function() {
var c = $(this)[0].getBoundingClientRect().width;
if( c > fitDivWidth ){fitDivWidth = c;}
});
tableWidth = $('.mainTable')[0].getBoundingClientRect().width;
$(this).css('flex','0 0 '+ 100/(tableWidth/fitDivWidth) +'%')
// Use remaining space equally for all other fluid column
$('.column').not(':first').not(this).css('flex','1 1 '+flexPercentage+'%')
expanded = thisInd;
}
// if second click on a fluid column
else
{
//Reset all fluid columns
$('.column').not(':first').css('flex','1 1 '+flexPercentage+'%')
expanded = '';
}
});
body{
font-family: 'Arial';
font-size: 12px;
padding: 20px;
}
.mainTable {
overflow: hidden;
width: 100%;
border: 1px solid black;
display: flex;
margin-top : 20px;
}
.cell{
height: 32px;
border-top: 1px solid black;
white-space: nowrap;
}
.cell:first-child{
background: #ccc;
border-top: none;
}
.column {
border-right: 1px solid black;
transition: flex 0.4s;
overflow: hidden;
line-height: 32px;
text-align: center;
}
.column:first-child {
background: #ccc;
}
.column:last-child {
border-right: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="text">Click on the header div you want to fit/reset (except the first one which is fixed)</span>
<div class="mainTable">
<div class="column">
<div class="cell"><span class="fit">Propriété</span></div>
<div class="cell"><span class="fit">Artisan 45</span></div>
<div class="cell"><span class="fit">Waterloo 528</span></div>
</div>
<div class="column">
<div class="cell"><span class="fit">Adresse</span></div>
<div class="cell"><span class="fit">Rue du puit n° 45 (E2)</span></div>
<div class="cell"><span class="fit">Chaussée de Waterloo n° 528 (E1)</span></div>
</div>
<div class="column">
<div class="cell"><span class="fit">Commune</span></div>
<div class="cell"><span class="fit">Ixelles</span></div>
<div class="cell"><span class="fit">Watermael-Boitsfort</span></div>
</div>
<div class="column">
<div class="cell"><span class="fit">Ville</span></div>
<div class="cell"><span class="fit">Marche-en-Famenne</span></div>
<div class="cell"><span class="fit">Bruxelles</span></div>
</div>
<div class="column">
<div class="cell"><span class="fit">Surface</span></div>
<div class="cell"><span class="fit">120 m<sup>2</sup></span></div>
<div class="cell"><span class="fit">350 m<sup>2</sup></span></div>
</div>
</div>
Und hier ist ein vollwertiges Beispiel bei der Arbeit (Stile + Auffüllen + mehr Daten):
https://jsfiddle.net/zrqLowx0/2/
Danke euch allen !
quelle
Antworten:
Es ist möglich, es mit
max-width
und zu lösencalc()
.Erstens ersetzen
width: 100%
mitflex: 1
der divs in CSS, so dass sie wachsen wird, was in diesem Fall besser ist. Verwenden Sie außerdem den Übergang fürmax-width
.Jetzt müssen wir einige relevante Werte speichern:
divsLength
variabel) - 3 in diesem Fall.extraSpace
variabel) - in diesem Fall 39px.Mit diesen beiden Variablen können wir einen Standardwert
max-width
(defaultMaxWidth
Variable) für alle Divs festlegen und diese später verwenden. Deshalb werden sie global gespeichert.Das
defaultMaxWidth
istcalc((100% - extraSpace)/divsLength)
.Geben Sie nun die Klickfunktion ein:
Um die div zu erweitern, wird die Breite des Zieltextes in einer Variablen aufgerufen werden gespeichert ,
textWidth
und es wird auf die div angewandt werden , wiemax-width.
es verwendet.getBoundingClientRect().width
(da sie den Fließkommawert zurück).Für die verbleibenden Divs wird ein
calc()
For erstelltmax-width
, das auf sie angewendet wird.Es ist :
calc(100% - textWidth - extraScape)/(divsLength - 1)
.Das berechnete Ergebnis ist die Breite, die jedes verbleibende Div haben sollte.
Wenn Sie auf das erweiterte div klicken, dh zur Normalität zurückkehren, wird die Standardeinstellung
max-width
erneut auf alle.div
Elemente angewendet .Dieser Ansatz verhält sich dynamisch und sollte bei jeder Auflösung funktionieren.
Der einzige Wert, den Sie für den Hardcode benötigen, ist die
extraSpace
Variable.quelle
Sie müssen sich mit den Breiten- oder Berechnungsfunktionen befassen. Flexbox hätte eine Lösung.
Um alle Divs gleich zu machen (nicht die erste), verwenden wir
flex: 1 1 auto
.Definieren Sie Flex-Regeln für Ihr normales Div und das ausgewählte Div.
transition: flex 1s;
ist dein Freund. Für ausgewählte benötigen wir kein Flex Grow, also verwenden wirflex: 0 0 auto
;Fügen Sie jedes Mal eine ausgewählte Klasse hinzu, wenn der Benutzer auf ein Div klickt. Sie können auch den Umschalter für den zweiten Klick verwenden, um ausgewählte Elemente in einer Karte zu speichern und mehrere ausgewählte Elemente anzuzeigen (natürlich nicht mit diesem Codebeispiel).
https://jsfiddle.net/f3ao8xcj/
quelle
Flex transition: Stretch (or shrink) to fit content
ist Ihr Fragentitel und diese Antwort ist das einfache Beispiel dafür. Es liegt in Ihrer Verantwortung, die Lösung für Ihren Fall zu finden.Nach einigen Testversionen scheint dies meine kürzeste und einfachste Lösung zu sein.
Alles , was sein muss , im Wesentlichen hat getan Flexbox die
<div>
Dehnungselemente standardmäßig an ihre Grenzen, aber wenn<span>
die Strecke von der angeklickt wird , Constraint<div>
zu<span>
Breite ...Pseudocode:
when <span> clicked and already toggled then <div> max-width = 100%, reset <span> toggle state
otherwise <div> max-width = <span> width, set <span> toggle state
Ich habe das CSS in einen Abschnitt "Relevanter Mechanismus" und "Nur Augenweide" unterteilt, um das Lesen (und das erneute Codieren von Code) zu erleichtern.
Der Code ist stark kommentiert, daher hier nicht viel Text ...
Quirk Irgendwie gibt es eine zusätzliche Verzögerung
transition
beim Umschaltendiv
von vonmax-width: 100%
aufmax-width = span width
. Ich habe dieses Verhalten in Chrome, Edge, IE11 und Firefox (alle W10) überprüft und alle scheinen diese Eigenart zu haben. Entweder wird eine interne Neuberechnung des Browsers durchgeführt, oder dietransition
Zeit wird zweimal verwendet ("fühlt sich an wie"). Umgekehrt gibt es seltsamerweise keine zusätzliche Verzögerung.Bei einer kurzen Übergangszeit (z. B. 150 ms, wie ich sie jetzt verwende) ist diese zusätzliche Verzögerung jedoch nicht / kaum spürbar. (Schön für eine andere SO-Frage ...)
Code-Snippet anzeigen
AKTUALISIEREN
Neue Version, die alle anderen zurücksetzt
<div>
. Ich hasse die Nervosität wirklich, aber das liegt an der Dehnung der Flexbox und demtransition
Wert. Ohnetransition
sichtbare Sprünge. Sie müssen ausprobieren, was für Sie funktioniert.Ich habe nur
document.querySelectorAll()
den Javascript-Code hinzugefügt .Code-Snippet anzeigen
quelle