Calc of max, ou max of calc em CSS

122

É possível fazer algo assim

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

ou

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

em CSS?

Arnaud
fonte
Você já os experimentou?
Kyle G.
5
Como @ gert-sønderby disse, basta usar estes dois: min-width: 500px; largura: calc (100% - 80 px);
paulie4

Respostas:

11

min(),, max()e clamp()finalmente estão disponíveis!

A partir do Firefox 75, Chrome 79 e Safari 11.1 (exceto clamp).

min()e max()aceite qualquer número de argumentos.

clamp()tem sintaxe clamp(MIN, VAL, MAX)e é equivalente a max(MIN, min(VAL, MAX)).

min()e max()pode estar aninhado. Eles podem ser usados ​​dentro calc()e fora dele, também podem conter expressões matemáticas, o que significa que você pode evitar calc()ao usá-las.

Portanto, o exemplo original pode ser escrito como:

max-width: max(500px, 100% - 80px);
do utilizador
fonte
1
Pelo que vale, o MS Edge para macOS (versão 81.0.416.68) também permite isso. Alguém poderia assumir que a versão do Windows também funciona. Não sei a versão mínima suportada.
jhelzer
1
O novo Edge é essencialmente o Chrome, suas versões seguem a do Chrome. Os dados completos de compatibilidade do navegador estão no final das páginas vinculadas.
usuário
115

Uma solução css 'pura' atualmente é possível agora usando consultas de mídia:

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

@media screen and (max-width: 500px) {
  .yourselector {
    max-width: 500px;
  }
}
Andy
fonte
3
Ótima solução! Eu usei-o realmente para a altura min, aparentemente, você pode usar consultas de mídia para max-heightbem +1
avishic
102

Não, você não pode. max()e min()foram retirados dos valores e unidades CSS3. No entanto, eles podem ser reintroduzidos nos valores e unidades CSS4 . Atualmente, não há especificações para eles, e as calc()especificações não mencionam que são válidas dentro de uma calc()função.

David Storey
fonte
1
Você pode usar o JavaScript para obter o estilo calculado (realmente o estilo usado) do elemento. Remova 80px e compare com 500 para ver qual é maior. Algo como var val = parseInt (window.getComputedStyle (el, null) .getPropertyValue ("width")) - 80) para obter a largura - 80 e el.style.maxWidth para definir a largura máxima.
David Storey
10
Obrigado. No entanto, eu preferiria uma solução CSS pura.
Arnaud
41
Sempre que houver uma pergunta sobre CSS e uma resposta começar com "Você pode usar JavaScript", ela estará incorreta. Há muitos motivos válidos para manter todo o código de apresentação em CSS. Tudo - não a maioria.
precisa saber é
8
Parece que min () e max () estão de volta no Módulo 4 de CSS Values ​​and Units Module (Rascunho do editor, 1 de setembro de 2017) Link: drafts.csswg.org/css-values/#calc-notation
Jakob E
5
Mas há uma solução para o problema, manter a rolagem para resposta @andy abaixo
Offirmo
44

Uma solução alternativa seria usar- widthse.

max-width: 500px;
width: calc(100% - 80px);
David Mangold
fonte
3
É uma boa ideia, mas se eu entendi a pergunta de @ Arnaud corretamente, ele quer a largura máxima de um 500pxou de outro 100% - 80px. Sua solução limita a largura máxima 500pxmesmo se 100% - 80pxfor maior.
Theophilus
2
Mas é o mesmo que usar, min()portanto, talvez seja útil para outras pessoas.
precisa saber é o seguinte
17
Parece-me que o uso de largura mínima em vez de largura máxima no exemplo acima pode ser equivalente ao comportamento solicitado.
Gert Sønder por
1
A resposta me ajudou a adicionar uma margem a um contêiner flexível quando a largura da página diminuiu. codepen.io/OBS/pen/wGrRJV
ofer.sheffer
Publiquei uma solução demonstrando que o comentário de @ GertSønderby é realmente a solução correta.
SherylHohman
13

Enquanto a resposta de @ david-mangold acima , estava "close", estava incorreta.
(Você pode usar a solução dele se quiser uma largura mínima , em vez de uma largura máxima ).

Esta solução demonstra que o comentário @ Gert-Sønderby a essa resposta faz trabalho:
A resposta deveria ter usado min-width, não max-width.

Isto é o que deveria ter dito:

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

Sim, use largura mínima mais largura para emular uma função max () .

Aqui está o código de código (é mais fácil ver a demonstração no CodePen, e você pode editá-la para seus próprios testes).

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

Dito isso, a resposta de Andy acima pode ser mais fácil de raciocinar e pode ser mais apropriada em muitos casos de uso.

Além disso, observe que , eventualmente, uma max()e uma min()função pode ser apresentado a CSS, mas a partir de abril 2019 não é parte da especificação.

SherylHohman
fonte
1
Por que o voto negativo? Tudo indicado está correto e todas as fontes foram vinculadas e creditadas.
21819 SherlockHohman
1

@Amaud Existe uma alternativa para obter o mesmo resultado?

Existe uma abordagem CSS não-js pura que alcançaria resultados semelhantes. Você precisaria ajustar o preenchimento / margem do contêiner de elementos pai.

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