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.