Calc of max, o max of calc in CSS


122

È possibile fare qualcosa di simile

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

o

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

in CSS?


Li hai provati tu stesso?
Kyle G.

5
Come ha detto @ gert-sønderby, usa semplicemente questi due: min-width: 500px; larghezza: calc (100% - 80px);
paulie4

Risposte:


11

min(), max()e clamp()sono finalmente disponibili!

A partire da Firefox 75, Chrome 79 e Safari 11.1 (tranne clamp).

min()e max()accetta un numero qualsiasi di argomenti.

clamp()ha la sintassi clamp(MIN, VAL, MAX)ed è equivalente a max(MIN, min(VAL, MAX)).

min()e max()può essere annidato. Possono essere utilizzati sia all'interno calc()che all'esterno di esso, possono anche contenere espressioni matematiche, il che significa che puoi evitare calc()quando li usi.

Pertanto l'esempio originale può essere scritto come:

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

1
Per quello che vale, MS Edge per macOS (versione 81.0.416.68) consente anche questi. Si presume che anche la versione per Windows funzioni. Non conosco la versione minima supportata.
jhelzer

1
Il nuovo Edge è essenzialmente Chrome, le sue versioni seguono quella di Chrome. I dati sulla compatibilità completa del browser si trovano alla fine delle pagine collegate.
utente

115

Una soluzione CSS "pura" è attualmente possibile utilizzando le media query:

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

@media screen and (max-width: 500px) {
  .yourselector {
    max-width: 500px;
  }
}

3
Ottima soluzione! L'ho usato in realtà per l'altezza minima, a quanto pare potresti usare anche le media query per max-height+1
avishic

102

No, non puoi. max()e min()sono stati eliminati da CSS3 Values ​​and Units. Tuttavia, possono essere reintrodotti in CSS4 Values ​​and Units . Al momento non ci sono specifiche per loro e la calc()specifica non menziona che entrambe sono valide all'interno di una calc()funzione.


1
È possibile utilizzare JavaScript per ottenere lo stile calcolato (in realtà lo stile utilizzato) dell'elemento. Rimuovi 80 px da esso e confrontalo con 500 per vedere quale è maggiore. Qualcosa come var val = parseInt (window.getComputedStyle (el, null) .getPropertyValue ("width")) - 80) per ottenere la larghezza - 80 e el.style.maxWidth per impostare la larghezza massima.
David Storey

10
Grazie. Tuttavia, preferirei una soluzione CSS pura.
Arnaud

41
Ogni volta che c'è una domanda CSS e una risposta inizia con "Puoi usare JavaScript", non è corretto. Ci sono molte valide ragioni per voler mantenere tutto il codice di presentazione in CSS. Tutti ... non la maggior parte.
b264

8
Sembra che min () e max () siano tornati in CSS Values ​​and Units Module Level 4 (Editor's Draft, 1 settembre 2017) Link: drafts.csswg.org/css-values/#calc-notation
Jakob E

5
MA c'è una soluzione al problema, continua a scorrere fino alla risposta di @andy di seguito
Offirmo

44

Una soluzione alternativa sarebbe usare widthse stesso.

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

3
Questa è una buona idea, ma se capisco correttamente la domanda di @Arnaud, vuole la larghezza massima di 500pxo 100% - 80px. La tua soluzione limita la larghezza massima 500pxanche se 100% - 80pxè maggiore.
Theophilus

2
Ma è come usare min()quindi forse utile agli altri.
Seika85

17
Mi sembra che l'uso di min-width invece di max-width nell'esempio sopra potrebbe essere un equivalente al comportamento richiesto, però.
Gert Sønderby

1
La risposta mi ha aiutato ad aggiungere un margine a un contenitore flessibile una volta che la larghezza della pagina si è ridotta. codepen.io/OBS/pen/wGrRJV
ofer.sheffer

Ho pubblicato una soluzione dimostrando che il commento di @ GertSønderby è effettivamente la soluzione corretta.
SherylHohman

13

Sebbene la risposta di @ david-mangold sopra fosse "vicina", non era corretta.
possibile utilizzare la soluzione se si vuole un minimo di larghezza, invece di un massimo di larghezza).

Questa soluzione dimostra che @ Gert-Sønderby commento a questa risposta fa il lavoro:
la risposta avrebbe dovuto usare min-width, non è max-width.

Questo è quello che avrebbe dovuto dire:

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

Sì, usa min-width più width per emulare una funzione max () .

Ecco il codepen (più facile vedere la demo su CodePen e puoi modificarlo per i tuoi test).

.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>

Detto questo, la risposta di @andy sopra potrebbe essere più facile da ragionare e potrebbe essere più appropriata in molti casi d'uso.

Si noti inoltre che eventualmente una funzione max()e una min()possono essere introdotte in CSS, ma a partire da aprile 2019 non fa parte delle specifiche.


1
Perché il voto negativo? Tutto quanto affermato è corretto e tutte le fonti sono state collegate e accreditate.
SherylHohman

1

@Amaud C'è un'alternativa per avere lo stesso risultato?

Esiste un approccio CSS puro non js che otterrebbe risultati simili. Dovresti regolare il riempimento / margine del contenitore degli elementi principali.

.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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.