Berechnung von max oder max von calc in CSS

122

Ist es möglich so etwas zu tun?

max-width: calc(max(500px, 100% - 80px))

oder

max-width: max(500px, calc(100% - 80px)))

in CSS?

Arnaud
quelle
Hast du sie selbst ausprobiert?
Kyle G.
5
Wie @ gert-sønderby sagte, verwenden Sie einfach diese beiden: min-width: 500px; Breite: calc (100% - 80px);
Paulie4

Antworten:

11

min(),, max()und clamp()sind endlich verfügbar!

Ab Firefox 75, Chrome 79 und Safari 11.1 (außer clamp).

min()und max()nehmen Sie eine beliebige Anzahl von Argumenten.

clamp()hat Syntax clamp(MIN, VAL, MAX)und entspricht max(MIN, min(VAL, MAX)).

min() und max() kann verschachtelt sein. Sie können sowohl innerhalb calc()als auch außerhalb verwendet werden. Sie können auch mathematische Ausdrücke enthalten, was bedeutet, dass Sie sie vermeiden können, calc()wenn Sie sie verwenden.

Daher kann das ursprüngliche Beispiel wie folgt geschrieben werden:

max-width: max(500px, 100% - 80px);
Benutzer
quelle
1
MS Edge für macOS (Version 81.0.416.68) erlaubt dies auch. Man würde annehmen, dass die Windows-Version auch funktioniert. Ich kenne die min-unterstützte Version nicht.
Jhelzer
1
Der neue Edge ist im Wesentlichen Chrome, seine Versionen folgen denen von Chrome. Die vollständigen Daten zur Browserkompatibilität befinden sich am Ende der verlinkten Seiten.
Benutzer
115

Eine "reine" CSS-Lösung ist jetzt tatsächlich mit Medienabfragen möglich:

.yourselector {
  max-width: calc(100% - 80px);
}

@media screen and (max-width: 500px) {
  .yourselector {
    max-width: 500px;
  }
}
Andy
quelle
3
Tolle Lösung! Ich habe es tatsächlich für max-height
minimale
102

Nein, du kannst nicht. max()und min()wurden aus CSS3-Werten und -Einheiten entfernt. Sie können jedoch in CSS4-Werten und -Einheiten wieder eingeführt werden . Derzeit gibt es keine Spezifikation für sie, und in der calc()Spezifikation wird nicht erwähnt, dass beide innerhalb einer calc()Funktion gültig sind .

David Storey
quelle
1
Sie können JavaScript verwenden, um den berechneten Stil (tatsächlich den verwendeten Stil) des Elements abzurufen. Entfernen Sie 80px und vergleichen Sie es mit 500, um festzustellen, welches größer ist. So etwas wie var val = parseInt (window.getComputedStyle (el, null) .getPropertyValue ("width")) - 80) zum Abrufen der width - 80 und el.style.maxWidth zum Festlegen der maximalen Breite.
David Storey
10
Danke dir. Ich würde jedoch eine reine CSS-Lösung bevorzugen.
Arnaud
41
Immer wenn eine CSS-Frage vorliegt und eine Antwort mit "Sie können JavaScript verwenden" beginnt, ist sie falsch. Es gibt viele triftige Gründe, den gesamten Präsentationscode in CSS behalten zu wollen. Alle - nicht die meisten.
B264
8
Es scheint, als wären min () und max () wieder im CSS-Werte- und Einheitenmodul Level 4 (Entwurf des Herausgebers, 1. September 2017). Link: Drafts.csswg.org/css-values/#calc-notation
Jakob E
5
ABER es gibt eine Lösung für das Problem, scrollen Sie weiter zu @andy Antwort unten
Offirmo
44

Eine Problemumgehung wäre, sich selbst zu verwenden width.

max-width: 500px;
width: calc(100% - 80px);
David Mangold
quelle
3
Dies ist eine gute Idee, aber wenn ich die Frage von @ Arnaud richtig verstehe, möchte er die maximale Breite von entweder 500pxoder 100% - 80px. Ihre Lösung begrenzt die maximale Breite auf, 500pxselbst wenn sie 100% - 80pxgrößer ist.
Theophilus
2
Aber es ist das gleiche wie zu verwenden, min()daher vielleicht hilfreich für andere.
Seika85
17
Es scheint mir jedoch, dass die Verwendung von min-width anstelle von max-width im obigen Beispiel dem angeforderten Verhalten entsprechen könnte.
Gert Sønderby
1
Die Antwort hat mir geholfen, einem Flex-Container einen Rand hinzuzufügen, sobald die Seitenbreite klein wurde. codepen.io/OBS/pen/wGrRJV
ofer.sheffer
Ich habe eine Lösung veröffentlicht, die zeigt, dass @ GertSønderbys Kommentar tatsächlich die richtige Lösung ist.
SherylHohman
13

Während die Antwort von @ david-mangold oben "nah" war, war sie falsch.
(Sie können seine Lösung verwenden, wenn Sie eine minimale Breite anstelle einer maximalen Breite wünschen ).

Diese Lösung zeigt, dass der Kommentar von @ gert-sønderby zu dieser Antwort funktioniert :
Die Antwort hätte verwendet werden sollen min-width, nicht max-width.

Das hätte es sagen sollen:

min-width: 500px;
width: calc(100% - 80px);

Ja, verwenden Sie min-width plus width , um eine max () -Funktion zu emulieren .

Hier ist der Codepen (die Demo auf CodePen ist einfacher zu sehen und Sie können sie für Ihre eigenen Tests bearbeiten).

.parent600, .parent500, .parent400 {
    height: 80px;
    border: 1px solid lightgrey;
}
.parent600 {
    width: 600px;
}
.parent500 {
    width: 500px;
}
.parent400 {
    width: 400px;
}

.parent600 .child, .parent500 .child, .parent400 .child {
    min-width: 500px;
    width: calc(100% - 80px);
    border: 1px solid blue;
    height:60px;
}

.ruler600 {
    width: 600px;
    border: 1px solid green;
    background-color: lightgreen;
    height: 20px;
    margin-bottom: 40px;
}
.width500 {
    height: 20px;
    width: 500px;
    background-color: lightyellow;
    float: left;
}
.width80 {
    height: 20px;
    width: 80px;
    background-color: green;
    float: right;
}

.parent600 .wrong, .parent500 .wrong, .parent400 .wrong {
    max-width: 500px;
    width: calc(100% - 80px);
    border: 1px solid red;
    height:60px;
}
<h2>(Min) min-width correctly gives us the Larger dimension: </h2>
<div class="parent600">
    600px parent
    <div class="child">child is max(500px, 600px - 80px) = max(500px, 520px) = 520px</div>
</div>

<div class="ruler600"><div class="width500">500px</div>20<div class="width80">80px</div></div>

<div class="parent500">
    500px parent
    <div class="child">child is max(500px, 500px - 80px) = max(500px, 420px) = 500px</div>
</div>

<div class="ruler600"><div class="width500">500px</div><div class="width80">80px</div></div>

<div class="parent400">
    400px parent (child expands to width of 500px)
    <div class="child">child is max(500px, 400px - 80px) = max(500px, 320px) = 500px</div>
</div>
<div class="ruler600"><div class="width500">500px</div><div class="width80">80px</div></div>


<h2>(Max) max-width <em>incorrectly</em> gives us the Smaller dimension: </h2>
<div class="parent400">
    400px parent
    <div class="wrong">child is min(500px, 400px - 80px) = min(500px, 320px) = 320px</div>
</div>
<div class="ruler600"><div class="width500">500px</div><div class="width80">80px</div></div>

<div class="parent500">
    500px parent
    <div class="wrong">child is min(500px, 500px - 80px) = min(500px, 420px) = 420px</div>
</div>

<div class="ruler600"><div class="width500">500px</div><div class="width80">80px</div></div>

<div class="parent600">
    600px parent
    <div class="wrong">child is min(500px, 600px - 80px) = min(500px, 520px) = 500px</div>
</div>

<div class="ruler600"><div class="width500">500px</div>20<div class="width80">80px</div></div>

Das heißt, @ andys Antwort oben über einfache Grund sein kann, und besser geeignet in vielen Anwendungsfällen sein.

Beachten Sie auch, dass möglicherweise eine max()und eine min()Funktion in CSS eingeführt werden, diese jedoch ab April 2019 nicht mehr Teil der Spezifikation ist.

SherylHohman
quelle
1
Warum das Downvote? Alles, was angegeben wird, ist korrekt und alle Quellen wurden verlinkt und gutgeschrieben.
SherylHohman
1

@Amaud Gibt es eine Alternative, um das gleiche Ergebnis zu erzielen ?

Es gibt einen reinen CSS-Ansatz, der nicht js ist und ähnliche Ergebnisse erzielt. Sie müssten die Auffüllung / den Rand des übergeordneten Elementcontainers anpassen.

.parent {
    padding: 0 50px 0 0;
    width: calc(50%-50px);
    background-color: #000;
}

.parent .child {
    max-width:100%;
    height:50px;
    background-color: #999;
}
<div class="parent">
  <div class="child"></div>
</div>

Jicub
quelle