CSS: Select 元素仅当存在较晚的兄弟时

CSS: Select element only if a later sibling exists

在我的 HTML 结构中,我是这样设置的:

<body>
   <main>
      <section>
      ...
      </section>

      <aside>
      ...
      </aside>
   </main>
</body>

问题是,并不是所有的页面都有<aside>

我需要 select <section> 并给它 max-width: 500px; 仅当 <aside> 存在时 。默认为 section { max-width: 1000px; }(当 <aside> 不存在时)

不同于Selector for one tag directly followed by another tag;用户 [提出问题] 想一直设置 "B" 样式。此外,在这个问题中,用户想要 select "B" (而不是 "A")


尽管这不是最简洁的做事方式,但您可以 运行 文档就绪 javascript 函数,检查 aside 标签是否存在,并插入内联 css 相应地添加到部分标签。

没有JAVASCRIPT

如果您可以将 html 元素的顺序更改为:

<body>
   <main>
      <aside>
      ...
      </aside>

      <section>
      ...
      </section>
   </main>
</body>

您可以使用同级选择器这样做:

aside ~ section {
    max-width: 500px;
}

使用 JavaScript 完成此操作会相当简单。

例如,这将起作用:

<script>
    window.onload = function() {
        if (document.getElementsByTagName('aside')[0]) {
           document.getElementsByTagName('section')[0].style.max-width = '500px';
        } else {
            document.getElementsByTagName('section')[0].style.max-width = '1000px';
        }
    }
</script>

在 CSS 中有相邻的兄弟选择器:http://www.w3.org/TR/CSS21/selector.html#adjacent-selectors

section + aside { ... }

所有现代浏览器都支持,包括 IE8+ 并且要小心:如果 section 和 aside 在文档树中共享相同的父节点并且 section immediately 在 aside

之前,则选择器匹配

如果这对您不起作用,您可以尝试 JavaScript 和 jQuery:

if($('aside').length)) $('section').addClass('specificSection');

然后将所有样式添加到 class '.specificSeciton'。

如果您有可能将您的元素放在第一节之前,您可以使用 adjacent sibling selectors:

aside + section{ max-width: 500px }

试试这个,我相信只有一些 javascript 才能做到。

if ($('main').find('aside').length>0)
{
    $('main').find('section').addClass('specificSection');
}

使用 jQuery,您可以尝试类似的操作:

if($('aside')) $('section').css('max-width','500px');

仅使用 CSS,您可以为包含 aside 的页面类型使用不同的样式,并且以某种方式仅在这些页面上包含该样式。您可以将该样式放入它自己的一个小样式表中,并在需要的地方包含它,这可能是一种比呈现页面然后使用 JavaScript.

更改它更简洁的方法

一个巧妙的小技巧

您可以通过使用技巧来检查 是否 <section> 元素是 <main>.[=52= 中的唯一元素来实现您想要的效果] 如果那里还有任何其他元素,这将不起作用。在你的情况下,它应该像这样工作(http://jsfiddle.net/Ljm323qb/2/):

section {
     max-width: 500px;
}
/* The STAR of the show */
section:only-child {
     max-width: 1000px;
}

如本代码笔所示:http://codepen.io/omarjuvera/pen/ByXGyK?editors=110


兄弟选择器的一般内容

+ select 或者 select 紧跟在元素 (https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_selectors)

之后的兄弟

还有 ~ select 或 select 所有以下兄弟姐妹 (https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_selectors)

您可以通过将 <aside> 元素放在 <section> 元素之前并使用兄弟元素 selector.

来实现它

举个例子:http://jsfiddle.net/Ljm323qb/1/

未来速览
很快这将成为可能,新的 :has 伪 class (http://dev.w3.org/csswg/selectors-4/#relational)
你可以调用 main:has(> aside) > section { ... } 之类的东西,但不幸的是,我们必须等待它:(

您可以使用 jQuery 将 class .haveSidebar 切换到 body 标签,并且为 section 标签设置 CSS 取决于此 class 是否存在于 body 标签中:

HTML

<main>
    <section>
    </section>

    <aside>
    </aside>
</main>

CSS

main {
    width:100%;
}
main aside {
    width:300px;
    background:red;
    min-height:300px;
    float:left;
}
main section {
    width:100%;
    background:green;
    min-height:300px;
    float:left;
}
body.haveSidebar main section {
    width: calc(100% - 300px);
}

JS

var sideBar = $('body > main > aside');
if (sideBar.length > 0) {
    $('body').addClass('haveSidebar');
} else {
    $('body').removeClass('haveSidebar');
}

Fiddle with aside tag

Fiddle without aside tag

更新

没有 calc() 的解决方案,使用 margin-left 属性

main aside {
    width:300px;
    background:red;
    min-height:300px;
    position:relative;
}
main section {
    width:100%;
    background:green;
    min-height:300px;
    float:left;
}
.haveSidebar main section {
    margin-left:301px;
}

Fiddle without calc()