Oblicz maks. Lub maks. Obliczeń w CSS


122

Czy można coś takiego zrobić

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

lub

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

w CSS?


Czy sam je wypróbowałeś?
Kyle G.

5
Jak powiedział @ gert-sønderby, po prostu użyj tych dwóch: min-width: 500px; szerokość: calc (100% - 80px);
paulie4

Odpowiedzi:


11

min(), max()i clamp()wreszcie są dostępne!

Począwszy od Firefox 75, Chrome 79 i Safari 11.1 (z wyjątkiem clamp).

min()i max()weź dowolną liczbę argumentów.

clamp()ma składnię clamp(MIN, VAL, MAX)i jest równoważne max(MIN, min(VAL, MAX)).

min()i max()mogą być zagnieżdżone. Mogą być używane zarówno w nim, calc()jak i poza nim, mogą również zawierać wyrażenia matematyczne, co oznacza, że ​​można ich unikać calc().

Dlatego oryginalny przykład można zapisać jako:

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

1
Co jest warte, MS Edge dla macOS (wersja 81.0.416.68) również na to pozwala. Można by przypuszczać, że działa również wersja dla systemu Windows. Nie znam minimalnej obsługiwanej wersji.
jhelzer

1
Nowa Edge to zasadniczo Chrome, jej wersje podążają za wersją Chrome. Pełne dane dotyczące zgodności przeglądarek znajdują się na końcu połączonych stron.
użytkownik

115

„Czyste” rozwiązanie CSS jest obecnie możliwe dzięki zapytaniom o media:

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

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

3
Świetne rozwiązanie! Użyłem go właściwie dla minimalnej wysokości, najwyraźniej możesz używać zapytań o media max-heightrównież dla +1
avishic

102

Nie, nie możesz. max()i min()zostały usunięte z CSS3 Values ​​and Units. Można je jednak ponownie wprowadzić w wartościach i jednostkach CSS4 . Obecnie nie ma dla nich specyfikacji, a calc()specyfikacja nie wspomina, że ​​którekolwiek z nich są prawidłowe w calc()funkcji.


1
Możesz użyć JavaScript, aby uzyskać obliczony styl (właściwie używany styl) elementu. Usuń z niego 80 pikseli i porównaj z 500, aby zobaczyć, który jest większy. Coś w rodzaju var val = parseInt (window.getComputedStyle (el, null) .getPropertyValue ("width")) - 80) do uzyskania szerokości - 80 i el.style.maxWidth do ustawienia maksymalnej szerokości.
David Storey

10
Dziękuję Ci. Wolałbym jednak czyste rozwiązanie CSS.
Arnaud

41
Za każdym razem, gdy pojawia się pytanie CSS, a odpowiedź zaczyna się od „Możesz użyć JavaScript”, jest niepoprawna. Istnieje wiele ważnych powodów, dla których warto zachować cały kod prezentacji w CSS. Wszyscy - nie większość.
b264

8
Wygląda na to, że min () i max () wróciły do ​​modułu wartości i jednostek CSS, poziom 4 ( wersja robocza
Jakob E

5
ALE jest rozwiązanie problemu, przewijaj dalej do odpowiedzi @andy poniżej
Offirmo

44

Obejściem byłoby użycie widthsamego siebie.

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

3
To dobry pomysł, ale jeśli dobrze rozumiem pytanie @Arnauda, ​​chce on mieć maksymalną szerokość jednego 500pxlub drugiego 100% - 80px. Twoje rozwiązanie ogranicza maksymalną szerokość, 500pxnawet jeśli 100% - 80pxjest większa.
Theophilus

2
Ale to to samo, co używanie, min()dlatego może być pomocne dla innych.
Seika85

17
Wydaje mi się, że użycie min-width zamiast max-width w powyższym przykładzie może być równoważne z żądanym zachowaniem.
Gert Sønderby

1
Odpowiedź pomogła mi dodać margines do kontenera elastycznego, gdy szerokość strony stała się mała. codepen.io/OBS/pen/wGrRJV
ofer.sheffer

Opublikowałem rozwiązanie pokazujące, że komentarz @ GertSønderby jest rzeczywiście właściwym rozwiązaniem.
SherylHohman

13

Chociaż odpowiedź @ david-mangold powyżej brzmiała „blisko”, była nieprawidłowa.
(Ty możesz wykorzystać swoje rozwiązanie, jeśli chcesz minimalną szerokość, zamiast maksymalnej szerokości).

Rozwiązanie to dowodzi, że @ Gert-Sønderby komentarz do tej odpowiedzi robi pracy:
Odpowiedź powinna być używana min-width, nie max-width.

Oto, co powinien był powiedzieć:

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

Tak, użyj min-width plus width, aby emulować funkcję max () .

Oto codepen (łatwiejsze do zobaczenia demo na CodePen i możesz je edytować do własnych testów).

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

To powiedziawszy, powyższa odpowiedź @ andy może być łatwiejsza do przemyślenia i może być bardziej odpowiednia w wielu przypadkach użycia.

Zwróć również uwagę, że ostatecznie a max()i min()funkcja mogą zostać wprowadzone do CSS, ale od kwietnia 2019 r. Nie jest to część specyfikacji.


1
Dlaczego głos przeciw? Wszystko, co podano, jest poprawne, a wszystkie źródła zostały powiązane i podane.
SherylHohman

1

@Amaud Czy istnieje alternatywa, aby uzyskać ten sam wynik?

Istnieje podejście do czystego CSS inne niż js, które przyniosłoby podobne wyniki. Konieczne byłoby dostosowanie dopełnienia / marginesu kontenera elementów nadrzędnych.

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.