Sass calcular porcentagem menos px

133

Quero poder fazer o seguinte:

height: 25% - 5px;

Obviamente, quando faço isso, recebo o erro:

Incompatible units: 'px' and '%'.
Mike Fielden
fonte
Eu recebo o Invalid property valueerro. Em todos os navegadores, incluindo a versão Canárias do Chrome.
Mike Fielden
Se existe uma função Sass thatd me conseguir o que quero isso é legal, eu estava apenas brincando com calc...
Mike Fielden
Sim :) Como eu disse, eu não me importo como isso é feito, calcfui eu primeiro e não funcionou. Parece que calcnão funciona em nenhum dos meus navegadores, então uma implementação sass seria melhor, eu acho.
Mike Fielden
1
O Sass não pode atuar como um polyfill para calc (). Ele não sabe converter 25% em px para fazer as contas e gerar o CSS. Dependendo de suas necessidades exatas, pode haver uma alternativa, como o uso da família display de mesa, mudando sua caixa-sizing, ou usar margens negativas ( jsfiddle.net/5JZGt )
cimmanon

Respostas:

239

O Sass não pode executar aritmética em valores que não podem ser convertidos de uma unidade para a seguinte. Sass não tem como saber exatamente o quão grande é "100%" em termos de pixels ou qualquer outra unidade. Isso é algo que apenas o navegador sabe.

Você precisa usar em seu calc()lugar. Verifique a compatibilidade do navegador em Posso usar ...

.foo {
    height: calc(25% - 5px);
}

Se seus valores estão em variáveis, pode ser necessário usar a interpolação para transformá-los em strings (caso contrário, o Sass apenas tenta executar aritmética):

$a: 25%;
$b: 5px;

.foo {
  width: calc(#{$a} - #{$b});
}
chrisgonzalez
fonte
5
Eu diria que o calc () não funciona na maioria dos navegadores. As plataformas móveis são tão importantes quanto os computadores.
21813 dalgard
3
Não há argumento, mas conte os navegadores! Mais suporte a calc () do que não, e ainda mais o suportará em um futuro próximo!
Chrisgonzalez
5
Eu tive problemas largura usando uma variável dentro das funções do Calc, mas encontrada aqui: stackoverflow.com/questions/13542164/... que eu poderia fazer referência a variável assim: calc(25% - #{$var}).
mlunoe
Para acompanhar a declaração de @ dalgard, em termos de navegadores lançados existentes, o calc não funciona mais do que funciona. Consulte: caniuse.com/#search=calc
imjared
3
Você sempre pode usar uma opção de retorno adicionando width: 22%acima de todos os widths comcalc
Hengjie 3/13
23

Há uma calcfunção no SCSS [tempo de compilação] e CSS [tempo de execução]. Você provavelmente está invocando o primeiro em vez do último.

Por razões óbvias, as unidades de mixagem não funcionam em tempo de compilação, mas em tempo de execução.

Você pode forçar o último usando unquote, uma função SCSS.

.selector { height: unquote("-webkit-calc(100% - 40px)"); }
sandstrom
fonte
14
$var:25%;
$foo:5px;
.selector {
    height:unquote("calc( #{$var} - #{$foo} )");
}
Edwin Fernando Marroquin Busto
fonte
2
Obrigado por postar uma resposta a esta pergunta! As respostas somente de código são desencorajadas no Stack Overflow, porque um despejo de código sem contexto não explica como ou por que a solução funcionará, dificultando o pôster original (ou futuros leitores) entender a lógica por trás disso. Edite sua pergunta e inclua uma explicação do seu código para que outras pessoas possam se beneficiar da sua resposta. Obrigado!
Maximillian Laumeister
Isso me salvou. width: unquote ("calc (100% - # {$ leftnav-width})");
Http
5

Se você souber a largura do contêiner, poderá fazer o seguinte:

#container
  width: #{200}px
  #element
    width: #{(0.25 * 200) - 5}px

Estou ciente de que, em muitos casos, o #container pode ter uma largura relativa. Então isso não funcionaria.

Design by Adrian
fonte
2

Desculpe por reviver o thread antigo - o alongamento da bússola com um pseudo-seletor: after pode atender ao seu objetivo - por exemplo. se você deseja que uma div preencha a largura da esquerda para (50% + 10px) da tela, você pode usar (na sintaxe recuada do SASS):

.example
    background: red
    +stretch(0, -10px, 0, 0)
    &:after
        +stretch(0, 0, 0, 50%)
        content: ' '
        background: blue

O elemento: after preenche 50% à direita do .example (deixando 50% disponível para a largura do .example) e, em seguida, o .example é estendido para essa largura mais 10px.

Bryce Gilhome
fonte
1
existe uma mistura menos ou menos para isso em algum lugar? O calc não parece funcionar muito bem.
v3nt
0

Basta adicionar o valor percentual em uma variável e usar #{$variable} por exemplo

$twentyFivePercent:25%;
.selector {
    height: calc(#{$twentyFivePercent} - 5px);
}
Aftab Ahmed
fonte