Calc dari max, atau max dari kalk di CSS

122

Apakah mungkin melakukan sesuatu seperti ini

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

atau

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

di CSS?

Arnaud
sumber
Sudahkah Anda mencobanya sendiri?
Kyle G.
5
Seperti yang dikatakan @ gert-sønderby, cukup gunakan dua ini: min-width: 500px; lebar: kalk (100% - 80px);
paulie4

Jawaban:

11

min(),, max()dan clamp()akhirnya tersedia!

Mulai di Firefox 75, Chrome 79, dan Safari 11.1 (kecuali clamp).

min()dan max()mengambil sejumlah argumen.

clamp()memiliki sintaks clamp(MIN, VAL, MAX)dan setara dengan max(MIN, min(VAL, MAX)).

min()dan max()mungkin bersarang. Mereka dapat digunakan di dalam calc()maupun di luarnya, mereka juga mungkin berisi ekspresi matematika, yang berarti Anda dapat menghindarinya calc()saat menggunakannya.

Oleh karena itu contoh aslinya dapat ditulis sebagai:

max-width: max(500px, 100% - 80px);
pengguna
sumber
1
Untuk apa nilainya, MS Edge untuk macOS (Versi 81.0.416.68) juga memungkinkan ini. Orang akan menganggap versi Windows juga berfungsi. Tidak tahu versi yang didukung min.
jhelzer
1
Edge baru pada dasarnya adalah Chrome, versinya mengikuti versi Chrome. Data kompatibilitas browser lengkap ada di akhir halaman tertaut.
pengguna
115

Solusi css 'murni' sebenarnya sekarang dimungkinkan dengan menggunakan kueri media:

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

@media screen and (max-width: 500px) {
  .yourselector {
    max-width: 500px;
  }
}
Andy
sumber
3
Solusi bagus! Saya sebenarnya telah menggunakannya untuk ketinggian minimum, tampaknya Anda juga dapat menggunakan kueri media untuk max-height+1
avishic
102

Tidak Anda tidak bisa. max()dan min()telah dihapus dari CSS3 Values ​​and Units. Namun, mereka dapat diperkenalkan kembali dalam Nilai dan Unit CSS4 . Saat ini tidak ada spesifikasi untuk mereka, dan calc()spesifikasi tidak menyebutkan bahwa keduanya valid di dalam suatu calc()fungsi.

David Storey
sumber
1
Anda bisa menggunakan JavaScript untuk mendapatkan gaya yang dihitung (sebenarnya gaya yang digunakan) dari elemen. Hapus 80px darinya dan bandingkan dengan 500 untuk melihat mana yang lebih besar. Sesuatu seperti var val = parseInt (window.getComputedStyle (el, null) .getPropertyValue ("width")) - 80) untuk mendapatkan lebar - 80 dan el.style.maxWidth untuk menyetel max-width.
David Storey
10
Terima kasih. Namun, saya lebih suka solusi CSS murni.
Arnaud
41
Kapan pun ada pertanyaan CSS dan tanggapan dimulai dengan "Anda dapat menggunakan JavaScript", itu salah. Ada banyak alasan yang valid untuk ingin menyimpan semua kode presentasi di CSS. Semua-- tidak kebanyakan.
b264
8
Sepertinya min () dan max () telah kembali di Modul Nilai dan Unit CSS Tingkat 4 (Draf Editor, 1 September 2017) Tautan: drafts.csswg.org/css-values/#calc-notation
Jakob E
5
TAPI ada solusi untuk masalah tersebut, terus scroll ke jawaban @andy di bawah ini
Offirmo
44

Solusinya adalah menggunakan widthdirinya sendiri.

max-width: 500px;
width: calc(100% - 80px);
David Mangold
sumber
3
Ini adalah ide yang bagus, tetapi jika saya memahami pertanyaan @ Arnaud dengan benar, dia menginginkan lebar maksimal dari salah satu 500pxatau 100% - 80px. Solusi Anda membatasi lebar maksimal 500pxbahkan jika 100% - 80pxlebih besar.
Theophilus
2
Tapi itu sama dengan menggunakan min()karena itu mungkin membantu orang lain.
Seika85
17
Menurut saya, menggunakan min-width alih-alih max-width dalam contoh di atas mungkin setara dengan perilaku yang diminta.
Gert Sønderby
1
Answer membantu saya menambahkan margin ke wadah fleksibel setelah lebar halaman menjadi kecil. codepen.io/OBS/pen/wGrRJV
ofer.sheffer
Saya memposting solusi yang menunjukkan komentar @ GertSønderby memang solusi yang tepat.
SherylHohman
13

Meskipun jawaban @ david-mangold di atas "hampir" ternyata salah.
(Anda dapat menggunakan solusinya jika Anda menginginkan lebar minimum , bukan lebar maksimum ).

Solusi ini mendemonstrasikan bahwa komentar @ gert-sønderby untuk jawaban itu berhasil:
Jawabannya seharusnya menggunakan min-width, bukan max-width.

Ini yang seharusnya dikatakan:

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

Ya, gunakan min-width plus width untuk meniru fungsi max () .

Berikut codepennya (lebih mudah untuk melihat demo di CodePen, dan Anda dapat mengeditnya untuk pengujian Anda sendiri).

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

Yang mengatakan, jawaban @ andy di atas mungkin lebih mudah untuk alasan tentang, dan mungkin lebih tepat dalam banyak kasus penggunaan.

Perhatikan juga, bahwa pada akhirnya a max()dan min()fungsi dapat diperkenalkan ke CSS, tetapi mulai April 2019 ini bukan bagian dari spesifikasi.

SherylHohman
sumber
1
Mengapa suara negatif itu? Semua yang dinyatakan benar, dan semua sumber telah ditautkan dan dikreditkan.
SherylHohman
1

@Amaud Apakah ada alternatif untuk mendapatkan hasil yang sama?

Ada pendekatan css murni non-js yang akan mencapai hasil serupa. Anda perlu menyesuaikan padding / margin wadah elemen induk.

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