Подтвердить что ты не робот

Как стиль переключателей по-разному, если они вписываются в одну строку?

PLAYGROUND ЗДЕСЬ

Я бы хотел по-разному погладить радио кнопки, если они вписываются в одну строку. Например:

enter image description here

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

Второй контейнер имеет достаточно места. Поэтому переключатели отображаются в виде кнопок.

Возможно ли достичь этого поведения только с помощью CSS?

Если нет, Javascript "взломать" приветствуется.

PLAYGROUND ЗДЕСЬ


HTML

<div class="container radio">
  <div>
    <input id="a1" type="radio" name="radio">
    <label for="a1">Yes,</label>
  </div>
  <div>
    <input id="a2" type="radio" name="radio">
    <label for="a2">it</label>
  </div>
  <div>
    <input id="a3" type="radio" name="radio">
    <label for="a3">is</label>
  </div>
  <div>
    <input id="a4" type="radio" name="radio">
    <label for="a4">possible</label>
  </div>
  <div>
    <input id="a5" type="radio" name="radio">
    <label for="a5">to</label>
  </div>
  <div>
    <input id="a6" type="radio" name="radio">
    <label for="a6">achieve</label>
  </div>
  <div>
    <input id="a7" type="radio" name="radio">
    <label for="a7">this</label>
  </div>
</div>
<div class="container buttons">
  <div>
    <input id="b1" type="radio" name="buttons">
    <label for="b1">Yes,</label>
  </div>
  <div>
    <input id="b2" type="radio" name="buttons">
    <label for="b2">it</label>
  </div>
  <div>
    <input id="b3" type="radio" name="buttons">
    <label for="b3">is</label>
  </div>
  <div>
    <input id="b4" type="radio" name="buttons">
    <label for="b4">possible</label>
  </div>
</div>

CSS (МЕНЬШЕ)

.container {
  display: flex;
  width: 220px;
  padding: 20px;
  margin-top: 20px;
  border: 1px solid black;

  &.radio {
    flex-direction: column;
  }

  &.buttons {
    flex-direction: row;

    > div {
      input {
        display: none;

        &:checked + label {
          background-color: #ADFFFE;
        }
      }

      label {
        padding: 5px 10px;
        margin: 0 1px;
        background-color: #ccc;
      }
    }
  }
}
4b9b3361

Ответ 1

Невозможно в CSS, но не нужно много JavaScript.

В CSS добавьте flex-shrink: 0 в > div. Это предотвратит сокращение числа детей .container меньше их размеров.

В JavaScript:

  • Примените класс buttons.
  • Используйте Element.getBoundingClientRect, чтобы определить, находится ли последний дочерний элемент .container вне степени .container. Если это так, переключитесь на класс radio. (Вам также нужно принять правильное дополнение во внимание. Благодаря @Moob для указания этого.)

Javascript

var container = document.querySelector('.container'),
    lastChild= document.querySelector('.container > :last-child'),
    paddingRight= parseInt(window.getComputedStyle(container, null).getPropertyValue('padding-right')),
    timer;

window.onresize = function() {
  clearTimeout(timer);
  timer= setTimeout(function() {
    container.classList.remove('radio');
    container.classList.add('buttons');
    if (container.getBoundingClientRect().right-paddingRight <
        lastChild.getBoundingClientRect().right) {
      container.classList.add('radio');
      container.classList.remove('buttons');
    }
  });
}

Обновлен JSBin

Ответ 2

Я не могу придумать решение только для CSS, но вы можете использовать JS для проверки того, будут ли элементы помещаться в строке и применять соответственно имя класса "радио" или "кнопки":

Простите мою грубую JS - ее неэлегантную и для современных браузеров, но вы получаете идею:

var containers = document.querySelectorAll(".container"),
test = function(){
    for (i = 0; i < containers.length; ++i) {
      var container = containers[i],
          divs = container.querySelectorAll("div"),
          iw = 0;
      container.classList.remove("radio");
      container.classList.add("buttons");
      //get the sum width of the div
      for (d = 0; d < divs.length; ++d) {
        iw+=divs[d].offsetWidth;
      }
      var style = window.getComputedStyle(container, null);
      var ow = parseInt(style.getPropertyValue("width"));
      if(ow<=iw){
          container.classList.add("radio");
          container.classList.remove("buttons");            
      }
    }
};

window.onresize = function(event) {
    test();
};
test();

http://jsbin.com/zofixakama/3/edit?html,css,js,output
(измените размер окна/панели, чтобы увидеть эффект)

Обновление. Если вы добавите стиль .container div {flex-shrink:0;} в стиль, JS может быть намного проще, поскольку нам не нужно измерять объединенную ширину div (спасибо @rick-hitchcock). Однако, хотя код более элегантный, он не учитывает контейнер padding.

Смотрите: http://jsbin.com/zofixakama/5/edit?html,css,js,output

Ответ 3

Если я правильно понимаю, что вы спрашиваете, вы можете изменить часть flex-direction на row вместо column. Это приведет к их выравниванию внутри поля.

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

Ответ 4

Попробуйте следующий пример.............. ------------ HTML -----------

<html>
<head>
 <link rel="stylesheet" href="style.css" type="text/css" /> 
</head>
<body>
    <div class="table-row">
        <div class="col">
                <input type="Radio">This
            </div>
            <div class="col" style="padding-top: 2px;">
                <input type="Radio">Is
            </div>  

            <div class="col">
                <input type="Radio">Simply
            </div>
            <div class="col" style="padding-top: 2px;">
                <input type="Radio">Possible
            </div>  

        </div>  
</body>
</html>

------- CSS -------------

.table-row{  
     display:table-row;     
     /* text-align: center; */
}
.col{
    display:table-cell;
    /* border: 1px solid #CCC; */
}

Ответ 5

Не будет ли он работать для проверки ширины, а при необходимости удалите значок переключателя и замените графикой или формой?

.checkbox {
    display:none;
}

.label {
    display: inline-block;
    height: 20px;
    background: url('picture.png');
}

Возможно, это не так просто, но я использую это для флажков и, похоже, работает в этой ситуации.

Ответ 6

Вы можете достичь этого только с помощью css и без необходимости создания сценариев.

HTML: вы должны поместить ввод в тег, который будет содержать текст.

<div>
<label for="a1">
    <input id="a1" type="radio" name="radio">Yes,
</label>  </div>

CSS: здесь, в CSS, нам нужно будет скрыть переключатель, чтобы отображался только текст. Когда пользователь нажимает на текст, он на самом деле нажимает на переключатель.

div lable input#a1{
   display:none;
}

Ответ 7

есть только решение только для CSS, но вам нужно знать максимальное количество элементов в строке. Он основан на счетчике, но не на реальном размере.

Например, если вы уверены, что вы можете поместить 4 элемента в строку, в любом случае вы можете использовать следующий селектор:

если количество меньше или равно 4:

div:nth-last-child(-n+5):first-child,
div:nth-last-child(-n+5):first-child ~ div {
    }

если сумма больше 4:

div:nth-last-child(n+5),
div:nth-last-child(n+5) ~ div {
}

попробуйте следующее: http://jsbin.com/fozeromezi/2/edit (просто удалите/добавьте div)