Como faço para definir um <div>
no centro da tela usando o jQuery?
Como faço para definir um <div>
no centro da tela usando o jQuery?
Respostas:
Eu gosto de adicionar funções ao jQuery, então essa função ajudaria:
jQuery.fn.center = function () {
this.css("position","absolute");
this.css("top", Math.max(0, (($(window).height() - $(this).outerHeight()) / 2) +
$(window).scrollTop()) + "px");
this.css("left", Math.max(0, (($(window).width() - $(this).outerWidth()) / 2) +
$(window).scrollLeft()) + "px");
return this;
}
Agora podemos escrever:
$(element).center();
Demo: Fiddle (com parâmetro adicionado)
<div>
vez de <body>
? Talvez você deve mudar window
para this.parent()
ou adicionar um parâmetro para isso.
Eu coloquei um plugin jquery aqui
VERSÃO MUITO CURTA
$('#myDiv').css({top:'50%',left:'50%',margin:'-'+($('#myDiv').height() / 2)+'px 0 0 -'+($('#myDiv').width() / 2)+'px'});
VERSÃO CURTA
(function($){
$.fn.extend({
center: function () {
return this.each(function() {
var top = ($(window).height() - $(this).outerHeight()) / 2;
var left = ($(window).width() - $(this).outerWidth()) / 2;
$(this).css({position:'absolute', margin:0, top: (top > 0 ? top : 0)+'px', left: (left > 0 ? left : 0)+'px'});
});
}
});
})(jQuery);
Ativado por este código:
$('#mainDiv').center();
VERSÃO PLUGIN
(function($){
$.fn.extend({
center: function (options) {
var options = $.extend({ // Default values
inside:window, // element, center into window
transition: 0, // millisecond, transition time
minX:0, // pixel, minimum left element value
minY:0, // pixel, minimum top element value
withScrolling:true, // booleen, take care of the scrollbar (scrollTop)
vertical:true, // booleen, center vertical
horizontal:true // booleen, center horizontal
}, options);
return this.each(function() {
var props = {position:'absolute'};
if (options.vertical) {
var top = ($(options.inside).height() - $(this).outerHeight()) / 2;
if (options.withScrolling) top += $(options.inside).scrollTop() || 0;
top = (top > options.minY ? top : options.minY);
$.extend(props, {top: top+'px'});
}
if (options.horizontal) {
var left = ($(options.inside).width() - $(this).outerWidth()) / 2;
if (options.withScrolling) left += $(options.inside).scrollLeft() || 0;
left = (left > options.minX ? left : options.minX);
$.extend(props, {left: left+'px'});
}
if (options.transition > 0) $(this).animate(props, options.transition);
else $(this).css(props);
return $(this);
});
}
});
})(jQuery);
Ativado por este código:
$(document).ready(function(){
$('#mainDiv').center();
$(window).bind('resize', function() {
$('#mainDiv').center({transition:300});
});
);
Isso está certo ?
De CSS-Tricks
.center {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%); /* Yep! */
width: 48%;
height: 59%;
}
Eu recomendaria o utilitário jQueryUI Position
$('your-selector').position({
of: $(window)
});
o que lhe dá muito mais possibilidades do que apenas centralizar ...
Aqui está a minha chance. Acabei usando-o para o meu clone do Lightbox. A principal vantagem dessa solução é que o elemento permanecerá centralizado automaticamente, mesmo se a janela for redimensionada, tornando-o ideal para esse tipo de uso.
$.fn.center = function() {
this.css({
'position': 'fixed',
'left': '50%',
'top': '50%'
});
this.css({
'margin-left': -this.outerWidth() / 2 + 'px',
'margin-top': -this.outerHeight() / 2 + 'px'
});
return this;
}
$(window).resize(function(){$('#mydiv').center()});
(mydiv é um diálogo modal, então quando ele é fechado para remover o manipulador de eventos de redimensionamento.)
outerWidth()
e outerHeight()
considerar o preenchimento e a largura da borda.
$(window).height()
dá 0. Mas mudei de posição para 'absoluto'.
Você pode usar CSS sozinho para centralizar da seguinte maneira:
.center{
position: absolute;
height: 50px;
width: 50px;
background:red;
top:calc(50% - 50px/2); /* height divided by 2*/
left:calc(50% - 50px/2); /* width divided by 2*/
}
<div class="center"></div>
calc()
permite fazer cálculos básicos em css.
Estou expandindo a ótima resposta dada por @TonyL. Estou adicionando Math.abs () para agrupar os valores e também levo em conta que o jQuery pode estar no modo "sem conflito", como, por exemplo, no WordPress.
Eu recomendo que você agrupe os valores superior e esquerdo com Math.abs (), como fiz abaixo. Se a janela for muito pequena e sua caixa de diálogo modal tiver uma caixa fechada na parte superior, isso impedirá o problema de não ver a caixa fechada. A função de Tony teria valores potencialmente negativos. Um bom exemplo de como você acaba com valores negativos é se você tiver uma grande caixa de diálogo centralizada, mas o usuário final instalou várias barras de ferramentas e / ou aumentou sua fonte padrão - nesse caso, a caixa de fechamento de uma caixa de diálogo modal (se na parte superior) pode não estar visível e clicável.
A outra coisa que faço é acelerar um pouco isso, armazenando em cache o objeto $ (window) para reduzir os desvios de DOM adicionais e usar um CSS de cluster.
jQuery.fn.center = function ($) {
var w = $(window);
this.css({
'position':'absolute',
'top':Math.abs(((w.height() - this.outerHeight()) / 2) + w.scrollTop()),
'left':Math.abs(((w.width() - this.outerWidth()) / 2) + w.scrollLeft())
});
return this;
}
Para usar, você faria algo como:
jQuery(document).ready(function($){
$('#myelem').center();
});
if (top < w.scrollTop()) top = w.scrollTop();
junto com o equivalente à esquerda. Novamente, isso fornece um comportamento diferente que pode ou não ser desejável.
Eu usaria a função UI do jQueryposition
.
Veja demonstração de trabalho .
<div id="test" style="position:absolute;background-color:blue;color:white">
test div to center in window
</div>
Se eu tiver uma div com id "test" para centralizar, o script a seguir centralizaria a div na janela no documento pronto. (os valores padrão para "meu" e "em" nas opções de posição são "centro")
<script type="text/javascript">
$(function(){
$("#test").position({
of: $(window)
});
};
</script>
Gostaria de corrigir um problema.
this.css("top", ( $(window).height() - this.height() ) / 2+$(window).scrollTop() + "px");
O código acima não funcionará nos casos em que this.height
((suponha que o usuário redimensione a tela e o conteúdo seja dinâmico) e scrollTop() = 0
, por exemplo:
window.height
é 600
this.height
é650
600 - 650 = -50
-50 / 2 = -25
Agora a caixa está centralizada -25
fora da tela.
Isso não foi testado, mas algo assim deve funcionar.
var myElement = $('#myElement');
myElement.css({
position: 'absolute',
left: '50%',
'margin-left': 0 - (myElement.width() / 2)
});
Eu não acho que ter uma posição absoluta seria melhor se você quiser um elemento sempre centralizado no meio da página. Você provavelmente quer um elemento fixo. Encontrei outro plugin de centralização de jquery que usava posicionamento fixo. É chamado centro fixo .
O componente de transição dessa função funcionou muito mal para mim no Chrome (não foi testado em outro lugar). Eu redimensionava muito a janela e meu elemento se movia lentamente, tentando recuperar o atraso.
Portanto, a seguinte função comenta essa parte. Além disso, adicionei parâmetros para passar booleanos x e y opcionais, se você deseja centralizar verticalmente, mas não horizontalmente, por exemplo:
// Center an element on the screen
(function($){
$.fn.extend({
center: function (x,y) {
// var options = $.extend({transition:300, minX:0, minY:0}, options);
return this.each(function() {
if (x == undefined) {
x = true;
}
if (y == undefined) {
y = true;
}
var $this = $(this);
var $window = $(window);
$this.css({
position: "absolute",
});
if (x) {
var left = ($window.width() - $this.outerWidth())/2+$window.scrollLeft();
$this.css('left',left)
}
if (!y == false) {
var top = ($window.height() - $this.outerHeight())/2+$window.scrollTop();
$this.css('top',top);
}
// $(this).animate({
// top: (top > options.minY ? top : options.minY)+'px',
// left: (left > options.minX ? left : options.minX)+'px'
// }, options.transition);
return $(this);
});
}
});
})(jQuery);
Para centralizar o elemento em relação à janela de exibição do navegador (janela), não use position: absolute
, o valor correto da posição deve serfixed
(significa absoluto: "O elemento está posicionado em relação ao seu primeiro elemento ancestral posicionado (não estático)").
Esta versão alternativa do plug-in central proposto usa "%" em vez de "px". Assim, quando você redimensiona a janela, o conteúdo é centralizado:
$.fn.center = function () {
var heightRatio = ($(window).height() != 0)
? this.outerHeight() / $(window).height() : 1;
var widthRatio = ($(window).width() != 0)
? this.outerWidth() / $(window).width() : 1;
this.css({
position: 'fixed',
margin: 0,
top: (50*(1-heightRatio)) + "%",
left: (50*(1-widthRatio)) + "%"
});
return this;
}
Você precisa colocar margin: 0
para excluir as margens do conteúdo da largura / altura (já que estamos usando a posição fixa, ter margens não faz sentido). De acordo com o documento jQuery, usando.outerWidth(true)
deve incluir margens, mas não funcionou como esperado quando tentei no Chrome.
O 50*(1-ratio)
vem de:
Largura da janela: W = 100%
Largura do elemento (em%): w = 100 * elementWidthInPixels/windowWidthInPixels
Para calcular a esquerda centralizada:
left = W/2 - w/2 = 50 - 50 * elementWidthInPixels/windowWidthInPixels =
= 50 * (1-elementWidthInPixels/windowWidthInPixels)
Isso é ótimo. Eu adicionei uma função de retorno de chamada
center: function (options, callback) {
if (options.transition > 0) {
$(this).animate(props, options.transition, callback);
} else {
$(this).css(props);
if (typeof callback == 'function') { // make sure the callback is a function
callback.call(this); // brings the scope to the callback
}
}
Se a pergunta me ensinou alguma coisa, é esta: não mude algo que já funcione :)
Estou fornecendo uma cópia (quase) literal de como isso foi tratado em http://www.jakpsatweb.cz/css/css-vertical-center-solution.html - ele foi fortemente invadido pelo IE, mas fornece uma maneira CSS pura de respondendo à pergunta:
.container {display:table; height:100%; position:absolute; overflow:hidden; width:100%;}
.helper {#position:absolute; #top:50%;
display:table-cell; vertical-align:middle;}
.content {#position:relative; #top:-50%;
margin:0 auto; width:200px; border:1px solid orange;}
Fiddle: http://jsfiddle.net/S9upd/4/
Eu executei isso através de browsershots e parece bom; se por nada mais, manterei o original abaixo, para que o tratamento da porcentagem da margem, conforme determinado pelas especificações CSS, veja a luz do dia.
Parece que estou atrasado para a festa!
Existem alguns comentários acima que sugerem que essa é uma questão de CSS - separação de preocupações e tudo. Permitam-me que anteceda isso dizendo que o CSS realmente deu um tiro no pé neste. Quero dizer, quão fácil seria fazer isso:
.container {
position:absolute;
left: 50%;
top: 50%;
overflow:visible;
}
.content {
position:relative;
margin:-50% 50% 50% -50%;
}
Direita? O canto superior esquerdo do contêiner estaria no centro da tela e, com margens negativas, o conteúdo reaparecerá magicamente no centro absoluto da página! http://jsfiddle.net/rJPPc/
Errado! O posicionamento horizontal é bom, mas verticalmente ... Entendo. Aparentemente, em css, ao definir as margens superiores em%, o valor é calculado como uma porcentagem sempre relativa à largura do bloco que o contém . Como maçãs e laranjas! Se você não confia em mim ou no Mozilla Doco, brinque com o violino acima, ajustando a largura do conteúdo e se surpreenda.
Agora, com CSS sendo meu pão com manteiga, eu não estava prestes a desistir. Ao mesmo tempo, prefiro as coisas fáceis, por isso peguei emprestadas as descobertas de um guru tcheco do CSS e a transformei em um violino. Para encurtar a história, criamos uma tabela na qual o alinhamento vertical é definido como o meio:
<table class="super-centered"><tr><td>
<div class="content">
<p>I am centered like a boss!</p>
</div>
</td></tr></table>
E a posição do conteúdo é ajustada com boa margem antiga : 0 automático; :
.super-centered {position:absolute; width:100%;height:100%;vertical-align:middle;}
.content {margin:0 auto;width:200px;}
Violino de trabalho conforme prometido: http://jsfiddle.net/teDQ2/
O que eu tenho aqui é um método "central" que garante que o elemento que você está tentando centralizar não seja apenas de posicionamento "fixo" ou "absoluto", mas também garante que o elemento que você está centralizando seja menor que o pai, esse centro e o elemento relativo a é pai, se o elemento pai for menor que o próprio elemento, ele empilha o DOM para o próximo pai e o centraliza em relação a isso.
$.fn.center = function () {
/// <summary>Centers a Fixed or Absolute positioned element relative to its parent</summary>
var element = $(this),
elementPos = element.css('position'),
elementParent = $(element.parent()),
elementWidth = element.outerWidth(),
parentWidth = elementParent.width();
if (parentWidth <= elementWidth) {
elementParent = $(elementParent.parent());
parentWidth = elementParent.width();
}
if (elementPos === "absolute" || elementPos === "fixed") {
element.css('right', (parentWidth / 2) - elementWidth / 2 + 'px');
}
};
você está sofrendo uma transição ruim porque está ajustando a posição do elemento toda vez que o documento é rolado. O que você deseja é usar o posicionamento fixo. Eu tentei o plugin do centro fixo listado acima e isso parece resolver o problema muito bem. O posicionamento fixo permite centralizar um elemento uma vez, e a propriedade CSS cuidará de manter essa posição sempre que você rolar.
Aqui está a minha versão. Eu posso mudar depois de olhar para esses exemplos.
$.fn.pixels = function(property){
return parseInt(this.css(property));
};
$.fn.center = function(){
var w = $($w);
return this.each(function(){
$(this).css("position","absolute");
$(this).css("top",((w.height() - $(this).height()) / 2) - (($(this).pixels('padding-top') + $(this).pixels('padding-bottom')) / 2) + w.scrollTop() + "px");
$(this).css("left",((w.width() - $(this).width()) / 2) - (($(this).pixels('padding-left') + $(this).pixels('padding-right')) / 2) + w.scrollLeft() + "px");
});
};
Não é necessário jquery para isso
Eu usei isso para centralizar o elemento Div. Estilo Css,
.black_overlay{
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index:1001;
-moz-opacity: 0.8;
opacity:.80;
filter: alpha(opacity=80);
}
.white_content {
display: none;
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
padding: 16px;
border: 16px solid orange;
background-color: white;
z-index:1002;
overflow: auto;
}
Elemento aberto
$(document).ready(function(){
$(".open").click(function(e){
$(".black_overlay").fadeIn(200);
});
});
MINHA ATUALIZAÇÃO PARA TONY L'S RESPOSTA
Esta é a versão modificada de sua resposta que uso religiosamente agora. Eu pensei em compartilhá-lo, pois adiciona um pouco mais de funcionalidade a ele para várias situações que você possa ter, como diferentes tipos de position
ou apenas querer centralização horizontal / vertical em vez de ambas.
center.js:
// We add a pos parameter so we can specify which position type we want
// Center it both horizontally and vertically (dead center)
jQuery.fn.center = function (pos) {
this.css("position", pos);
this.css("top", ($(window).height() / 2) - (this.outerHeight() / 2));
this.css("left", ($(window).width() / 2) - (this.outerWidth() / 2));
return this;
}
// Center it horizontally only
jQuery.fn.centerHor = function (pos) {
this.css("position", pos);
this.css("left", ($(window).width() / 2) - (this.outerWidth() / 2));
return this;
}
// Center it vertically only
jQuery.fn.centerVer = function (pos) {
this.css("position", pos);
this.css("top", ($(window).height() / 2) - (this.outerHeight() / 2));
return this;
}
No meu <head>
:
<script src="scripts/center.js"></script>
Exemplos de uso:
$("#example1").centerHor("absolute")
$("#example2").centerHor("fixed")
$("#example3").centerVer("absolute")
$("#example4").centerVer("fixed")
$("#example5").center("absolute")
$("#example6").center("fixed")
Ele funciona com qualquer tipo de posicionamento e pode ser usado em todo o site com facilidade, além de ser facilmente transportável para qualquer outro site que você criar. Soluções alternativas irritantes para centralizar algo corretamente.
Espero que isso seja útil para alguém por aí! Aproveitar.
Muitas maneiras de fazer isso. Meu objeto é mantido oculto com display: nenhum dentro da tag BODY, para que o posicionamento seja relativo ao BODY. Depois de usar $ ("# object_id"). Show () , eu chamo $ ("# object_id"). Center ()
Eu uso posição: absoluto porque é possível, especialmente em um pequeno dispositivo móvel, que a janela modal seja maior que a janela do dispositivo; nesse caso, parte do conteúdo modal poderá ficar inacessível se o posicionamento for corrigido.
Aqui está o meu sabor com base nas respostas dos outros e nas minhas necessidades específicas:
$.fn.center = function () {
this.css("position","absolute");
//use % so that modal window will adjust with browser resizing
this.css("top","50%");
this.css("left","50%");
//use negative margin to center
this.css("margin-left",(-1*this.outerWidth()/2)+($(window).scrollLeft())+"px");
this.css("margin-top",(-1*this.outerHeight()/2)+($(window).scrollTop())+"px");
//catch cases where object would be offscreen
if(this.offset().top<0)this.css({"top":"5px","margin-top":"0"});
if(this.offset().left<0)this.css({"left":"5px","margin-left":"0"});
return this;
};
Você pode usar a translate
propriedade CSS :
position: absolute;
transform: translate(-50%, -50%);
Leia este post para mais detalhes.
left: 50%
e, em top: 50%
seguida, você pode usar a conversão de transformação para mudar seu ponto central corretamente. No entanto, com esse método, navegadores como o Chrome distorcerão / emborcarão seu texto posteriormente, o que geralmente não é desejável. É melhor pegar a largura / altura da janela e posicionar a esquerda / parte superior com base nisso, em vez de mexer na transformação. Evita distorções e funciona em todos os navegadores em que eu testei.
Normalmente, eu faria isso apenas com CSS ... mas como você pediu uma maneira de fazer isso com o jQuery ...
O código a seguir centraliza uma div horizontal e verticalmente dentro de seu contêiner:
$("#target").addClass("centered-content")
.wrap("<div class='center-outer-container'></div>")
.wrap("<div class='center-inner-container'></div>");
body {
margin : 0;
background: #ccc;
}
.center-outer-container {
position : absolute;
display: table;
width: 100%;
height: 100%;
}
.center-inner-container {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.centered-content {
display: inline-block;
text-align: left;
background: #fff;
padding : 20px;
border : 1px solid #000;
}
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.1.min.js"></script>
<div id="target">Center this!</div>
(veja também este violino )
Solução CSS Apenas em duas linhas
Centraliza sua divisão interna horizontal e verticalmente.
#outer{
display: flex;
}
#inner{
margin: auto;
}
apenas para alinhamento horizontal, altere
margin: 0 auto;
e para vertical, troque
margin: auto 0;
Por que você não usa CSS para centralizar uma div?
#timer_wrap{
position: fixed;
left: 50%;
top: 50%;
}