Динамические Адаптивные Формы с использованием CSS
Я пытаюсь создать форму ввода пользователя с несколькими полями / значениями в табличном формате. Если это рабочий стол, он должен показывать 6 столбцов (по паре имя / значение поля в каждом), а если его телефон (портретный режим) должен показывать только 2. Если он в альбомной ориентации, показывать 4 столбца.
Ожидаемый результат: телефон (портрет)
+--------+---------+
+ Field + Value +
+--------+---------+
+ Field + Value +
+--------+---------+
+ Field + Value +
+--------+---------+
Телефон (ландшафтный режим)
+--------+---------+--------+---------+
+ Field + Value + Field + Value +
+--------+---------+--------+---------+
+ Field + Value + Field + Value +
+--------+---------+--------+---------+
+ Field + Value + Field + Value +
+--------+---------+--------+---------+
iPad или больше
+--------+---------+--------+---------+--------+---------+--------+---------+
+ Field + Value + Field + Value + Field + Value + Field + Value +
+--------+---------+--------+---------+--------+---------+--------+---------+
+ Field + Value + Field + Value + Field + Value + Field + Value +
+--------+---------+--------+---------+--------+---------+--------+---------+
Я хочу, чтобы это был чистый CSS (насколько это возможно), так как контент будет заполнен угловым конструктором позже.
Тем не менее, я не получаю правильный поток, поскольку divs, кажется, слипаются и не отрываются чистыми как ряд! Возможно, я что-то здесь упускаю. Он прекрасно работает в портретном режиме телефона, но, как вы можете видеть на рисунке ниже, он повсюду.
Код Pen: Ссылка
Вот код на данный момент:
<div class='table-type'>
<div class='row-type'>
<div class='cell-type'>Account</div>
<div class='cell-type'>Acme Incorporated US and Seychelles</div>
<div class='cell-type'>Geography</div>
<div class='cell-type'>North America</div>
<div class='cell-type'>Premier</div>
<div class='cell-type'>Yes</div>
<div class='cell-type'>Countact Count</div>
<div class='cell-type'>23</div>
<div class='cell-type'>Account Manager</div>
<div class='cell-type'>Dustin Brown</div>
<div class='cell-type'>Customer Engineer</div>
<div class='cell-type'>David Hoff</div>
<div class='cell-type'>Exec Sponsor</div>
<div class='cell-type'>Jeff Larabee</div>
</div>
</div>
Теперь CSS:
.table-type
{
display: table;
margin-bottom: 5px;
width:100%;
table-layout: fixed;
}
.row-type
{
display: table-row;
}
.cell-type
{
float: left;
margin-top: 2px;
margin-bottom: 2px;
padding: 5px;
line-height: 16px;
font-family: 'Lato', sans-serif;
border: 4px solid;
border-color: #fff;
border-radius: 15px;
border-spacing: 15px 15px;
}
.cell-type:nth-child(odd)
{
text-align: right;
}
.cell-type:nth-child(even)
{
text-align:left;
font-weight: bold;
-webkit-border-radius:15px;-moz-border-radius:15px;
background-color: #e3f2f2;
}
@media (max-width: 500px)
{
.cell-type:nth-child(3n+3)
{
display: block;
}
.cell-type:nth-child(odd)
{
width:30%;
}
.cell-type:nth-child(even)
{
width:70%;
}
}
@media (max-width: 700px) and (min-width: 501px)
{
.cell-type:nth-child(odd)
{
width:20%;
}
.cell-type:nth-child(even)
{
width:30%;
}
.cell-type:nth-child(5n+5)
{
display: block;
}
}
@media (min-width: 701px)
{
.cell-type:nth-child(odd)
{
width:13%;
}
.cell-type:nth-child(even)
{
width:20%;
}
.cell-type:nth-child(7n+7)
{
display: block;
}
}
2 ответа
Я думаю, что будет легче достичь желаемого результата с помощью flexbox
:
.row-type {
display: flex;
flex-wrap: wrap;
}
.cell-type {
flex: 0 0 10%
/* translates to: flex-grow: 0;
* flex-shrink: 0;
* flex-basis: 10%;
*/
}
.cell-type:nth-child(even) {
flex-basis: 15%;
/* 10% + 15% = 25% */
}
Но первая проблема, которую нужно решить, это применить box-sizing:border-box
ко всем вашим клеткам. Это изменит способ учета отступов и границ, которые будут включены в width
собственность (или flex-basis
для flexbox), поэтому вам не нужно устанавливать проценты и вычитать отступы и размеры границ.
Затем нужно просто указать правильные размеры ваших ячеек в зависимости от ширины родительского элемента. Для этого выберите направление (от большого к маленькому или от маленького к большому). Я выбирал от большого к маленькому внизу, но делал это и от маленьких до больших работ.
Напишите правила для вашего первого выбранного интервала за пределами любого @media
запрос перед @media
запросы (это важно, потому что селекторы внутри вашего @media
запросы будут иметь одинаковую специфику с запросами извне и правилами внутри @media
будет применяться исключительно на том факте, что они размещены позже в CSS).
Помните: @media
запросы не меняют специфику. Они только устанавливают, применяются ли правила внутри на основании предоставленного условия. Таким образом, правила, установленные до @media
запросы будут применяться только тогда, когда ни один из ваших последующих @media
запросы (переопределяя их) верны.
Затем, используя те же самые точные селекторы, напишите свои правила для следующего интервала внутри соответствующего @media
править и продолжать, пока не дойдете до последнего @media
править. Вам нужно только переписать изменяемое свойство, которое в данном случае flex-basis
, В случае таблиц это будет width
,
Я также считаю, что ваши контрольные точки немного сбиты, как 700px
а также 500px
слишком низки для вашей таблицы (я решил разбить их с 8 до 6/ ряд в 1200px
от 6 до 4/ ряд в 950px
и от 4 до 2/ строка в 650px
). Не стесняйтесь не соглашаться и корректировать их в соответствии с вашими потребностями и предпочтениями.
Вот:
.table-type {
margin-bottom: 5px;
width: 100%;
}
.row-type {
display: flex;
flex-wrap: wrap;
align-items: stretch; /* you might also try `center` here */
}
.cell-type {
display: block;
flex: 0 0 10%;
margin: 3px 0;
padding: 7px 12px;
line-height: 16px;
min-height: 46px; /* added for equal height cells. removed on mobile */
font-family: 'Lato', sans-serif;
border-radius: 16px;
box-sizing: border-box;
}
.cell-type:nth-child(odd) {
text-align: right;
}
.cell-type:nth-child(even) {
flex-basis: 15%;
font-weight: bold;
background-color: #eaf5f5;
box-shadow: inset 0 1px 3px rgba(0,0,0,.06), inset 0 1px 1px rgba(0,0,0,.04), inset 0 2px 1px rgba(0,0,0,.03)
}
@media(max-width: 1200px) {
.cell-type:nth-child(odd) {
flex-basis: 13.3333%;
}
.cell-type:nth-child(even) {
flex-basis: 20%;
}
}
@media(max-width: 950px) {
.cell-type:nth-child(odd) {
flex-basis: 20%;
}
.cell-type:nth-child(even) {
flex-basis: 30%;
}
}
@media(max-width: 650px) {
.cell-type {
min-height:0;
}
.cell-type:nth-child(odd) {
flex-basis: 40%;
}
.cell-type:nth-child(even) {
flex-basis: 60%;
}
}
<div class='table-type'>
<div class='row-type'>
<div class='cell-type'>Account</div>
<div class='cell-type'>Acme Incorporated US and Seychelles</div>
<div class='cell-type'>Geography</div>
<div class='cell-type'>North America</div>
<div class='cell-type'>Premier</div>
<div class='cell-type'>Yes</div>
<div class='cell-type'>Countact Count</div>
<div class='cell-type'>23</div>
<div class='cell-type'>Account Manager</div>
<div class='cell-type'>Dustin Brown</div>
<div class='cell-type'>Customer Engineer</div>
<div class='cell-type'>David Hoff</div>
<div class='cell-type'>Exec Sponsor</div>
<div class='cell-type'>Jeff Larabee</div>
</div>
</div>
Этого также можно добиться с помощью блочной модели (используя floats
). Сделать примечание display:table
(и это связанные реквизиты для подэлементов) и box-model
не играйте хорошо вместе. И под этим я подразумеваю: чтобы сделать клетки обертывающимися там, где вы хотите, вам нужно одно из:
- на самом деле обернуть ячейки одной строки внутри одного отдельного элемента DOM с
display:table-row
(так работает табличная модель). - использовать поплавки (модель коробки), установив
display:block
как в ряду, так и в ячейке иfloat:left
на клетки. Этот метод также требует очистки после правильного конца ячейки строки, чтобы избежать смещения ячеек в неправильном положении, когда у вас есть различия в высоте между ячейками.
Это то, что вы хотите?
.row-type
{
display: grid;
justify-items: center;
align-items: center;
}
...
@media (max-width: 500px)
{
.row-type{
grid-template-columns: repeat(2,1fr);
}
}
@media (max-width: 700px) and (min-width: 501px)
{
.row-type{
grid-template-columns: repeat(4,1fr);
}
}
@media (min-width: 701px)
{
.row-type{
grid-template-columns: repeat(8,1fr);
}
}