2014-01-23 3 views
2

TLDR: this codepen отлично работает в Chrome, но выравнивание отключено в Firefox.Свертывание разметки в Firefox

Я строю jQuery plugin, который изменяет ввод текста, чтобы дать ему кнопку выпадающего меню слева. Для того, чтобы получить право позиционирования, добавить оболочку DIV, которая является такой же высоты, как на входе, так что кнопка может быть абсолютно позиционирован на верхней части ввода, и все еще имеют одинаковую высоту:

#wrapper { 
    position: relative; 
} 
#overlay { 
    position: absolute; 
    top: 0; 
    bottom: 0; 
    width: 30px; 
} 

Это работает отлично, пока на входе нет вертикального поля: тогда контейнер растет, чтобы включить маржу, и поэтому кнопка раскрывающегося списка растет вместе с ней. Моим решением для этого был крах: я дал входной дисплей: блок, который означал, что контейнер проигнорировал его маржу. Все хорошо.

input { 
    margin: 20px 0 40px; /* testing */ 
    display: block; 
} 

Но теперь проблема в том, что по умолчанию входы являются встроенными элементами, например. вам может понадобиться кнопка отправки рядом с входом. Таким образом, я завернул все это в контейнер div с дисплеем: встроенный блок, поэтому другой встроенный элемент, такой как кнопка, может радостно сидеть рядом с ним.

#container { 
    display: inline-block; 
} 

Это прекрасно работает в Chrome, но имеет странные проблемы с выравниванием в Firefox, когда на входе есть какой-либо вертикальный запас. Ниже я добавил окончательную разметку. В верхней части также есть кодовая кнопка.

<div id="container"> 
    <div id="wrapper"> 
    <input> 
    <div id="overlay"></div> 
    </div> 
</div> 
<button>Submit</button> 

Редактировать: дело в том, что это плагин, и я пытаюсь работать с существующей пользовательской разметки и CSS, например, они имеют эту разметку:

<input><button>Submit</button> 

и их существующий CSS имеет вертикальный запас на входе, и я хочу, чтобы иметь возможность просто инициализирует свой плагин на входе и просто работать, не заставляя их изменить разметку/CSS. Теперь, поскольку плагин должен добавить много разметки вокруг ввода (для наложения и выпадающего списка), я завершаю все это в контейнер div. Этот контейнер div является пределом нашего охвата (и не включает элемент кнопки или что-то еще, что они предпочитают ставить рядом с их входами).

ответ

2

Чтобы исправить это, вам необходимо определить line-height у вашего родителя div#test2. Без него, different browsers will give it different values. Это заставит Firefox вызвать этот странный результат.

Теперь проблема line-height - это не единственная проблема, также базовое значение vertical-align создаст другой результат для встроенных элементов, чем для элементов встроенного блока, которые имеют разную высоту, чем окружающий встроенный контент. Чтобы исправить это, измените значение на top для элемента #container (так как это элемент inline-block).

Конечный результат будет иметь следующие изменения (только оклейки деталей, которые изменили):

#test2 { 
    background-color: green; 
    line-height:70px; 
    #container { 
     // replicate the inline nature of the input 
     display: inline-block; 
     vertical-align:top; 
    } 
    //the rest of the #test2 nested code 
} 

Это будет выглядеть this.

Ответить на комментарий

Я сделал то, что делает работу с требованиями. Поскольку вы сказали, что дополнительный код (так что divs вокруг ввода) сделаны самим плагином, я позволил себе немного изменить это, чтобы сделать эту работу.

Способ, которым он может работать довольно легко, просто не использует встроенные блоки вообще и придерживается встроенных элементов. Это изменило бы стили к следующим:

#container { 
    // replicate the inline nature of the input 
    display: inline; 
} 
#wrapper { 
    display: inline; 
    position: relative; 
} 
input { 
    // you'll want to make sure the typed text doesn't appear behind the overlay 
    padding-left:35px; 
} 
#overlay { 
    position: absolute; 
    top: 0px; 
    bottom: 0px; 
    left: 1px; 
    width: 30px; 
    background-color: #00C2FF; 
} 

Примечания:

  • Я не стал делать наложение покрытия на всю высоту входа, так как ваш плагин будет просто сделать его флаг в любом случае , Чтобы он покрывал всю высоту, просто установите отрицательные top и bottom стили на наложении, равные вычисленному отступу и верхнему дну (соответственно) на входе. В этом случае вам придется изменить их на top:-5px;bottom:-5px;.(вы можете получить вычисленный стиль через jQuery's $(input).css('padding-top'))
  • Вы также можете удалить из него весь #container, так как единственный стиль, который он имеет сейчас, - display:inline, который на самом деле ничего не добавляет ко всему.
  • Я добавил на ваш вход отступы слева, потому что в противном случае вам придется вводить за оверлей, что просто глупо.
+0

Очень крутое решение, но мне грустно говорить, что это невозможно. Я обновил вопрос, чтобы быть предельно ясным о том, что можно и не может быть изменено. – jackocnr

+0

@jackocnr, пожалуйста, см. Мой обновленный ответ. Это то, что ты искал? – Joeytje50

+1

Ничего себе! Так просто и так эффективно! Это лучший ответ. Единственное, что мешает мне отмечать награду, это то, что вам нужно знать прописку на входе, чтобы расположить оверлей, но заполнение задается пользователем (чтобы соответствовать их существующему стилю). Я полагаю, что обходным решением было бы взломать CSS с помощью jQuery, но этого я и хотел избежать. Если никто не придет с лучшим ответом, я дам вам щедрость. Спасибо! – jackocnr

0

«Отказ от ответственности»: Позвольте мне только начать с того, что я не нашел точно, что вызывает проблемы в Firefox, но я подумал об альтернативном способе, которым вы могли бы это сделать.

Как это работает и в Firefox и Chrome просто использовать один и тот же HTML, который вы использовали для #test1, но на вершине этого, также с помощью CSS :before псевдо-элемент (вместо того, чтобы использовать #container и #wrapper). Код я использовал:

#test2 { 
    background-color: green; 
    position:relative; 
    &:before { 
     content:""; 
     display:block; 
     position:absolute; 
     left:1px; 
     top:1px; 
     bottom:1px; 
     margin:20px 0 40px 0; 
     width:30px; 
     background:#00C2FF; 
    } 
} 

demo

Как это работает просто расположить :before накладки на том же месте, как дивы были ранее. Как вы можете видеть, я использовал большинство тех же стилей, что и вы, но вместо этого я разместил их на псевдоклассе :before.

+0

Спасибо за это. Интересный подход, но мне не нужен цветной квадрат для наложения: мне определенно нужно использовать реальную (довольно сложную) разметку, которую я не думаю, что это решение позволяет? – jackocnr

+0

@ jackocnr well Я бы не знал, не знаю, какая разметка вам понадобится. Не могли бы вы сослаться на демонстрацию того, что вы хотите сделать? Тогда я мог бы попытаться понять, будет ли это работать с ': before' для вас. Кроме того, вы можете сделать [намного больше, чем то, что я сделал] (https://developer.mozilla.org/en-US/docs/Web/CSS/content#Syntax) с свойством 'content'': before 'псевдоэлемент. – Joeytje50

+3

В вопросе на странице Github плагина есть ссылка, в которой содержится более подробная информация о плагине, включая ссылку на демонстрационную версию. – jackocnr

1

Является ли HTML-код, созданный плагином, и он должен оставаться абсолютно таким же? Я не уверен, что могу точно понять, почему второй пример не работает, но у вас, похоже, слишком много элементов div.Вы могли бы сделать так проще:

HTML

<div id="test1"> 
    <div id="wrapper"> 
    <input> 
    <div id="overlay"></div> 
    <button>submit</button> 
    </div> 
</div> 

SCSS

input, button { 
    border: 1px solid black; 
    padding: 5px; 
} 

input { 
    display: inline-block; 
    padding-left: 35px; 
} 

#test1 { 
    background-color: yellow; 
    padding: 20px 0 40px 0; 
    #wrapper { 
    position: relative; 
    #overlay { 
     position: absolute; 
     top: 1px; 
     left: 1px; 
     width: 30px; 
     background-color: #00C2FF; 
    } 
    } 
} 

Codepen example

я удалил запас, а вместо этого используется обивка на родителя, он достигает того же вещь. Вам также понадобится padding-left в вашем поле ввода, чтобы введенный текст не исчез за вашим оверлеем div.

EDIT: В случае, если вы не в состоянии изменить разметку:

SCSS:

#test2 { 
    background-color: green; 
    #container { 
    // replicate the inline nature of the input 
    display: inline-block; 
    padding: 20px 0 40px 0; 
    } 
    #wrapper { 
    // this is just here to be display:block and ignore the margin on the input 
    display: block; 
    position: relative; 
    } 
    input { 
    // tell parent to ignore margin 
    //display: block; 
    margin: 0; 
    } 
    #overlay { 
    position: absolute; 
    top: 1px; 
    bottom: 1px; 
    left: 1px; 
    width: 30px; 
    background-color: #00C2FF; 
    } 
} 

codepen demo

Удалены block и margin объявления от input поля, и переместил расстояние до заполнение элемента #container.

+0

Если вопрос касался исправления вопроса о марже, удаление это как обман ... Но, может быть, вы правы, и маржа не нужна, так что это случай [проблема XY] (http: //meta.stackexchange. ком/вопросы/66377/что-это-The-ху-проблема). – Oriol

+0

Спасибо за ваши предложения, но дело в том, что я пытаюсь работать с существующей разметкой пользователя и CSS, например. у них есть и их существующий CSS имеет вертикальный запас на входе, и я хочу, чтобы они могли просто инициализировать мой плагин, и он просто работает, без хлопот по изменению их разметки/CSS – jackocnr

+1

Так что переопределите свой по умолчанию css, чтобы соответствовать их потребностям. Никто не жалуется на это jQuery, и другие плагины не работают прямо из коробки. Решение этой проблемы, в свою очередь, может привести к другой проблеме. Тем не менее, возможно, вы должны отредактировать свой вопрос, чтобы точно указать, что можно и не может быть изменено. – jammykam

0

Другие ответы не знают, почему он не работает в Firefox. Ну, я думаю, что Firefox имеет правильное поведение, и это проблема Chrome.

Короче говоря, вы хотите выровнять вход с помощью кнопки. Но вход внутри оболочки. Затем вы можете использовать vertical-align для управления выравниванием по вертикали между оберткой и кнопкой, но не между входом и кнопкой.

Здесь вы можете увидеть скриншот с различными vertical-align:

Screenshot with different <code>vertical-align</code>

the code См.

Если вы хотите выровнять входной сигнал и кнопку (последний случай на изображении), у вас возникнет проблема, потому что любое из ключевых слов, которое вы можете использовать с vertical-align, делает это. Только в том случае, если верхний край ввода и нижнее поле равны, то работает vertical-align: middle.

Но в целом у вас есть другое решение: vertical-align также принимает значение <length>.

И, чтобы получить идеальное выравнивание, вы должны использовать формулу

vertical-align: -(input bottom margin) 

Или, если вы хотите, чтобы выровнять их, даже если кнопка имеет нижний край, затем

vertical-align: -(input bottom margin) + (button button margin) 

Формула кода выше работает с inline-block<div>, но не с <buttons>.

формула должна быть прикреплена к

vertical-align: -(input bottom margin) -(input offsetHeight)/2 + 6 

В вашем примере

  • (Входное нижнее поле) = 40px
  • (вход offsetHeight) = 31px

Затем, вам необходимо

vertical-align: -(input bottom margin) -(input offsetHeight)/2 + 6 

Demo

+0

«Другие ответы не знают, почему это не работает на Firefox» - не верно, см. Мой второй ответ. – Joeytje50

+0

Благодарим вас за этот просветительский ответ, но, к сожалению, поле является неизвестной переменной, заданной пользователем. Извините, если это неясно - я отредактировал вопрос, чтобы прояснить это. – jackocnr

+0

@jackocnr Да, но если это плагин jQuery, вы можете обнаружить маржу с помощью JS и установить «vertical-align» в зависимости от нее. – Oriol

0

Я мог бы достичь этого со следующим. Codepen Вы должны знать CSS применяется для ввода и применить его к кнопке, а

button{ 
    position:absolute; 
    margin-left:5px; 
    } 
    input, button { 
    display: inline-block; 
    margin: 20px 0 40px 0; 
    } 
-1

пожалуйста, обновите ниже в коде.

input, button { 
    border: 1px solid #000000; 
    margin: 20px 0 40px; 
    padding: 5px; 
    vertical-align: top; 
} 

надеюсь, что он будет работать

http://codepen.io/anon/pen/Isycu

+0

Нет - прочитайте вопрос - кнопка находится вне контроля плагина. – jackocnr

Смежные вопросы