2015-04-01 2 views
1

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

<div class="fieldset"> 
    <p>Normal Input<i class="icon-question tooltip-top" title="Text Goes Here"></i></p> 
    <div> 
     <span><i class="icon-cart"></i></span> 
     <input name=""> 
     <span><i class="icon-cart"></i></span> 
     <i class="icon-question tooltip-top" title="Text Goes Here"></i> 
    </div> 
</div> 

Я пытаюсь изменить настройки границы радиуса, согласно которой <input> позиционируется.

Например, если <input> имеет <span> непосредственно перед ним, его радиус границы будет равен нулю сверху и снизу слева.

Я сделал это с помощью:

.fieldset > div > span + input { 
    border-radius: 0 4px 4px 0; 
} 

Но, когда есть <span> после <input> входного радиус границы должен быть равен нулем только из правой верхней и нижней стороны. Очевидно, я не могу использовать селектор + для этого.

Как достичь желаемых результатов, когда <span> после <input> без использования JavaScript и изменения HTML?

UPDATE:

После ответов ниже и особенно методов BoltClock ♦ - кажется, что эта проблема почти решена! На приведенном ниже рисунке показаны все различные сценарии и код, используемый для их применения.

enter image description here Единственный сценарий, который еще не работает, - это когда перед входом имеется только один интервал.

Текущий CSS является:

/*Fieldsets*/ 
.fieldset { 
    width: 100%; 
    display: table; 
    position: relative; 
    white-space: nowrap; 
    margin-bottom: 15px; 
} 

.fieldset:last-of-type { 
    margin-bottom: 0; 
} 

     /*Fieldsets > Labels*/ 
     .fieldset > p { 
      width: 1%; 
      margin-bottom: 3px; 
     } 

     /*Fieldsets > Input Container*/ 
     .fieldset > div { 
      display: table-row; 
      position: relative; 
     } 

      .fieldset > div > * { 
       display: table-cell; 
       white-space: nowrap; 
       vertical-align: middle; 
       position: relative; 
      } 

      /*Fieldsets > Input + Icon*/ 
      .fieldset > div > span { 
       border: 1px solid #B0C2CE; 
       padding: 5px 15px; 
       font-weight: bold; 
       width: 1%; 
      } 

      /*Fieldsets > Input + Icon Senarios*/ 
      .fieldset > div > span:first-of-type { 
       border-right: 0; 
       border-radius: 4px 0 0 4px; 
      } 

      .fieldset > div > span:last-of-type { 
       border-left: 0; 
       border-radius: 0 4px 4px 0; 
      } 

      .fieldset > div > span:not(:only-of-type) + input { 
       border-radius: 0; 
      } 

      .fieldset > div > span + input, 
      .fieldset > div > span + textarea, 
      .fieldset > div > span + select, 
      .fieldset > div > span + .select-dropdown-single .select-dropdown-input, 
      .fieldset > div > span + .select-dropdown-multi .select-input { 
       border-radius: 0 4px 4px 0; 
      } 

      /*Fieldsets > Input + Help toolTip icon*/ 
      .fieldset > div [class^="tooltip-"], 
      .fieldset > div [class*=" tooltip-"] { 
       text-align: center; 
       width: 30px; 
      } 

HTML-:

<div class="fieldset"> 
       <p>Normal Input</i></p> 
       <div> 
        <input name=""> 
       </div> 
      </div> 

      <div class="fieldset"> 
       <p>Normal Input</p> 
       <div> 
        <span><i class="icon-cart"></i></span> 
        <input name=""> 
       </div> 
      </div> 

      <div class="fieldset"> 
       <p>Normal Input</p> 
       <div> 
        <span><i class="icon-cart"></i></span> 
        <input name=""> 
        <span><i class="icon-cart"></i></span> 
       </div> 
      </div> 

      <div class="fieldset"> 
       <p>Normal Input</p> 
       <div> 
        <span><i class="icon-cart"></i></span> 
        <input name=""> 
        <span><i class="icon-cart"></i></span> 
        <i class="icon-question tooltip-top" title="Text Goes Here"></i> 
       </div> 
      </div> 
+0

Вы можете изменить html-код? если _yes_ просто добавляет класс в ваш диапазон в зависимости от того, где он находится. –

+0

Я могу просто предоставить основной контейнер классу соответственно, но я хочу посмотреть, есть ли способ сделать это без необходимости изменять HTML. – Leo

+0

ну, вы должны добавить 'border-radius 0' в'.fieldset> div> input + span' (если span является прямым братом после ввода) –

ответ

3

Как правило, вы не можете таргетировать элемент, который является предыдущим родным братом другого элемента, независимо от того, f HTML, потому что there is no previous sibling selector.

Однако, учитывая вашу структуру, существует ряд возможных случаев, которые по-прежнему могут учитываться при использовании того, что в настоящее время доступно для вас. Если в этом элементе <div> будет находиться не более одного <span> с обеих сторон от <input> или с обеих сторон, и никакие другие элементы <span>, вы сможете установить таргетинг на <input> во всех этих случаях.

, как указано в вопросе, когда есть <span> элемент появляется только перед<input>, используют смежный селектор родственный, чтобы предназначаться для <input>:

<div class="fieldset"> 
    <p>Normal Input<i class="icon-question tooltip-top" title="Text Goes Here"></i></p> 
    <div> 
     <span><i class="icon-cart"></i></span> 
     <input name=""> 
     <i class="icon-question tooltip-top" title="Text Goes Here"></i> 
    </div> 
</div> 
.fieldset > div > span + input { 
    border-radius: 0 4px 4px 0; 
} 

Когда есть <span> элемент появляется только после<input>, то если это вызывает <input>, чтобы быть первым ребенком его родителя <div>, вы можете се :first-child целевой, что <input> только в такой ситуации:

<div class="fieldset"> 
    <p>Normal Input<i class="icon-question tooltip-top" title="Text Goes Here"></i></p> 
    <div> 
     <input name=""> 
     <span><i class="icon-cart"></i></span> 
     <i class="icon-question tooltip-top" title="Text Goes Here"></i> 
    </div> 
</div> 
.fieldset > div > input:first-child { 
    border-radius: 4px 0 0 4px; 
} 

Когда <span> элементы появляются до и после в <input>, вы можете использовать :not(:only-of-type) на первом <span> с соседним селектором родственного, чтобы предотвратить сопоставив это в первую очередь <span> в такой ситуации:

<div class="fieldset"> 
    <p>Normal Input<i class="icon-question tooltip-top" title="Text Goes Here"></i></p> 
    <div> 
     <span><i class="icon-cart"></i></span> 
     <input name=""> 
     <span><i class="icon-cart"></i></span> 
     <i class="icon-question tooltip-top" title="Text Goes Here"></i> 
    </div> 
</div> 
.fieldset > div > span:not(:only-of-type) + input { 
    border-radius: 0; 
} 

В качестве бонуса, так как вы имеете дело с border-radius собственности, иметь в виду, что вы можете использовать его longhands выборочно, чтобы избежать необходимости иметь дело с третьего случая (<span> с обеих сторон) в целом:

.fieldset > div > input { 
    border-radius: 4px; 
} 

.fieldset > div > span:only-of-type + input { 
    border-top-left-radius: 0; 
    border-bottom-left-radius: 0; 
} 

.fieldset > div > input:first-child { 
    border-top-right-radius: 0; 
    border-bottom-right-radius: 0; 
} 

Обратите внимание на использование :only-of-type в этом случае, однако, чтобы предотвратить совпадение селектора, если на обеих сторонах присутствуют элементы <span>.

+0

Спасибо, я использовал ответ «До и после», и это сработало. Тем не менее, ваш ответ на «Только после» не был, причина в том, что может быть не все промежутки и только вход в div. Поэтому вход будет иметь нулевой радиус справа и снизу независимо. Он должен иметь нулевой радиус, когда имеется интервал. – Leo

+1

@ Leo: Хорошая точка. Отсутствие пробелов немного усложняет ситуацию, но это все равно выполнимо. Является ли этот элемент единственным другим возможным родным братом? Если это так, вы можете настроить таргетинг на ввод, если нет пропусков, используя 'input: first-child: nth-last-child (2)' - это предполагает, что последний дочерний элемент - это i, и эффективно означает «Выберите вход, который первый из ровно двух детей в своем родителе ». – BoltClock

+0

Спасибо, что так много! Пожалуйста, прочтите мое обновление в моем вопросе выше. – Leo

1

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

Нет, нет селекторов, выделяющих предыдущих родственных (Is there a previous sibling selector?)

Существует только проект в следующей версии CSS: http://dev.w3.org/csswg/selectors-4/#general-sibling-combinators

0

В вашем конкретном случае (если ваш HTML не изменяет много из вашего примера), вы можете использовать что-то вроде этого:

попробуйте удалить/прокомментировать первый пролет и увидеть разницу.Было бы просто применить border-radius: 0 ко всем входным элементам за исключением тех, где предыдущий элемент является span

// EDIT

теперь вы можете увидеть разницу напрямую, без комментирования необходимо

.fieldset > div > input { 
    border-radius: 0; 
} 

.fieldset > div > span + input { 
    border-radius: 0 4px 4px 0 !important; 
} 

JSFiddle

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