CSS 100%宽度但避免使用滚动条

时间:2010-08-22 14:45:57

标签: css

这可能是已经解决了几十次的变化,但CSS确实让我觉得自己像个傻瓜。

我正在尝试构建一个可以通过各种方式定位和调整大小的小部件。这是一个非常简单的布局 - 固定高度的标题,固定高度的页脚,以及占据剩余空间的主体。整体宽度和高度各不相同。身体的内容需要滚动。我有整体容器,页眉,页脚和身体尺寸确定。

但我想要的是身体在需要时滚动当滚动条出现时不向左缩小内容。也就是说,我希望身体尽可能宽,以便滚动它所需的滚动条,这样当它需要滚动时就没有收缩。实际上,我想要这个:

| - - - unknown width - - -|
+--------------------------+
| content                |*|
| might                  |*|
| scroll                 |*|
+--------------------------+

我希望可以滚动的内容尽可能宽,以减少潜在的滚动条宽度(| * | region)。

我现在拥有的是这样的:

<div id="content" style="position: absolute; overflow-y: auto; width: 100%">
    <div id="scrollContent" style="???">
    </div>
</div>

我已经尝试了内部最大div的余量,填充,甚至%-widths以及所有“做转移”的事情。我还需要这个在FF3,IE7 / 8和(幻想?)IE6中工作。

11 个答案:

答案 0 :(得分:14)

使用overflow: scroll代替overflow: auto - 这会强制滚动条始终显示。

答案 1 :(得分:4)

The answer by Mattias Ottosson提供了至关重要的信息-vw单位基于视口宽度(包括滚动条),而百分比将基于可用宽度的宽度包括滚动条占用的空间。换句话说,对于占据页面整个宽度的元素,滚动条的宽度可以表示为calc(100vw - 100%)

如果我们有一个顶层元素占用了可用宽度的100%,那么我们可以使用它来控制滚动条可见时更改大小的内容。假设我们的目标布局是这样的:

.app {
  display: grid;
  grid-template-columns: 1fr 50vh 1fr;
}

在此我们希望中间列的宽度是视口高度的50%,其余宽度在左右列之间划分。如果使用了该功能,则添加滚动条意味着丢失给滚动条的水平空间(在chrome上约为15px)将从左右列的宽度中平均取出。当ui更改导致滚动条出现而网格中的主要内容保持相同或相似时,这可能导致难看的转变。请参见下面的第一个代码段。

我们可以使用计算出的滚动条宽度来仅缩小右列:

.app {
  display: grid;
  grid-template-columns: calc((100vw - 50vh)/2) 50vh calc(100% - (50vh + 100vw)/2);
}

请参阅下面的第二个片段。不幸的是,这意味着不能使用fr单位,并且必须手动指定一些列的宽度。在这种情况下,左列的宽度是视口宽度的一半减去中心列占用的50vh。右列的宽度是减去左列和中央列的组合宽度后,可用宽度100%而不是100vw剩余的空间。在公式中更清楚:

calc(100% - ((100vw - 50vh)/2) - (50vh))

减少到上述之一

第一个代码段,出现滚动条时会出现丑陋的跳转

$('button').click(() => {
  $('.footer').toggle()
})
body, html {
  height: 100%;
  width: 100%;
  padding: 0;
  margin: 0;
  overflow: auto;
  font-family: 'Archivo', sans-serif ;
}
.app {
  margin: auto;
  display: grid;
  grid-template-columns: 1fr 50vh 1fr;
  text-align: center;
  height: 100%;
  width: calc(100% - 10px);
}
.left-column, .center-column, .right-column {
  padding: 10px;
  min-height: 50vh;
  border: 1px solid black;
}
.left-column {
  border-right: none;
  background-color:#def;
}
.center-column {
  background-color:#e1ebbd;
}
.right-column {
  text-align: left;
  border-left: none;
  background: #fb1;
}
.footer {
  grid-column: 1 / span 3;
  height: 2000px;
  background: #753;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

</head>
<body>
  <div class="app">
    <div class="left-column">
      Left
    </div>
    <div class="center-column">
      Center
<script src="https://code.jquery.com/jquery-3.1.0.js"></script><br>
      <button>Toggle footer</button>
    </div>
    <div class="right-column">
      Right
    </div>
    <div class="footer">
 </div>
  </div>
</body>
</html>

第二个摘要,出现滚动条时,右列会缩小

$('button').click(() => {
  $('.footer').toggle()
})
body, html {
  height: 100%;
  width: 100%;
  padding: 0;
  margin: 0;
  overflow: auto;
  font-family: 'Archivo', sans-serif ;
}
.app {
  margin: auto;
  display: grid;
  grid-template-columns: calc((100vw - 50vh)/2) 50vh calc(100% - (50vh + 100vw)/2);
  text-align: center;
  height: 100%;
  width: calc(100% - 10px);
}
.left-column, .center-column, .right-column {
  padding: 10px;
  min-height: 50vh;
  border: 1px solid black;
}
.left-column {
  border-right: none;
  background-color:#def;
}
.center-column {
  background-color:#e1ebbd;
}
.right-column {
  text-align: left;
  border-left: none;
  background: #fb1;
}
.footer {
  grid-column: 1 / span 3;
  height: 2000px;
  background: #753;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

</head>
<body>
  <div class="app">
    <div class="left-column">
      Left
    </div>
    <div class="center-column">
      Center
<script src="https://code.jquery.com/jquery-3.1.0.js"></script><br>
      <button>Toggle footer</button>
    </div>
    <div class="right-column">
      Right
    </div>
    <div class="footer">
 </div>
  </div>
</body>
</html>

答案 2 :(得分:3)

在元素内添加另一个包装器,它将具有overflow:auto样式并将其设置为约18px更窄。滚动条应出现在18px的间隙中。

答案 3 :(得分:1)

为什么不总是显示滚动条,即使不需要滚动?

您可以通过将overflow:scroll;设置为容器来实现此目的。

答案 4 :(得分:1)

我遇到的问题与我使用下面的解决方案类似,我不确定这是否可以解决您想要做的事情,但可能是。

我有一个自动重新调整为内容的div,然后添加了滚动,缩小了内部,使其中的表包裹文本,而不是使容器更宽。如果向下调整textarea的大小并显示滚动,则可以在下面的旧示例中看到不需要的效果。

我丑陋的解决方案是在overflow-y:auto-div中添加一个div,它有display:inline-block,并在它之后添加另一个小的inline-block div,它是19像素宽(保留给滚动条)和像素高。当浏览器将div调整为内容时,那个小div会出现在真正的div旁边,当滚动条出现时,小div会在真正的div下面被推下来,真正的div会让它保持不变。它将导致一个像素底部&#34;边缘&#34;,但希望不是问题。当没有滚动条ppears时,真实div旁边有19个未使用空格像素,如问题中所述。

(最外面的div只是为了复制我的设置/问题。)

旧:

<div style="display:inline-block">
  <div style="max-height:120px; overflow-y:auto; border:1px solid gray">
    <table border=1><tr>
       <td>I do not</td><td>want this to</td>
       <td>add breaks in the text.</td>
    </tr></table>
    <textarea rows=3 cols=15>Resize me down</textarea>
  </div>
</div>
<br>

新:

<div style="display:inline-block">
  <div style="max-height:150px;overflow-y:auto; border:1px solid gray">
    <div style="display:inline-block">
      <table border=1><tr>
          <td>I do not</td><td>want this to</td>
          <td>add breaks in the text.</td>
      </tr></table>
      <textarea rows=3 cols=15>Resize me down</textarea>
    </div>
    <div style="display:inline-block; width:19px; height:1px"></div>
  </div>
</div>
<br>

答案 5 :(得分:1)

You can do it with using this css on the content element: `calc(100% - 15px)`.
// calc(100% - the width we want to give on right hand side of content)

请阅读以下内容以检查其工作原理。

使用overflow:scroll.

绝对是修复该问题的最简单,最轻松的方式

但是,如果您不想在不需要滚动条时显示滚动条,则应使用viewport(vw)的宽度,而不是100%。当滚动条进入视口宽度时,如果我们知道滚动条的宽度,则可以使用以下公式完成任务。在这里,我将内容宽度设置为视口宽度减去滚动条的宽度(假设15像素)。

您需要提供以下宽度:calc(100% - 15px)。您可以以%,em等形式提供宽度。

最好是,如果您像下面那样覆盖滚动条的宽度,然后在公式中使用该宽度值减去。

/* width */
::-webkit-scrollbar {
  width: 10px;
} 
#content {
  width: calc(100% - 10px).
}

注意:Firefox或Edge(早期版本79)不支持自定义滚动条。该CSS仅在webkit浏览器中可用,因此在IE中可能不起作用。

因此,您可以使用20px的最大宽度来减去,因为滚动条的宽度绝不能超过20px。请在下面找到工作代码。

.scroll {
    height: 100px;
    overflow: auto;
    border: 1px solid black;
    width: 75%;
}

.zui-table {
      width: calc(100% - 10px);
    border: solid 1px #DDEEEE;
    border-collapse: collapse;
    border-spacing: 0;
    font: normal 13px Arial, sans-serif;
}
.zui-table thead th {
    background-color: #DDEFEF;
    border: solid 1px #DDEEEE;
    color: #336B6B;
    padding: 10px;
    text-align: left;
    text-shadow: 1px 1px 1px #fff;
}
.zui-table tbody td {
    border: solid 1px #DDEEEE;
    color: #333;
    padding: 10px;
    text-shadow: 1px 1px 1px #fff;
}
<div class="scroll">
  <table class="zui-table">
    <thead>
      <tr>
        <th>Name</th>
        <th>Position</th>
        <th>Height</th>
        <th>Born</th>
        <th>Salary</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>DeMarcus Cousins</td>
        <td>C</td>
        <td>6'11"</td>
        <td>08-13-1990</td>
        <td>$4,917,000</td>
      </tr>
      <tr>
        <td>Isaiah Thomas</td>
        <td>PG</td>
        <td>5'9"</td>
        <td>02-07-1989</td>
        <td>$473,604</td>
      </tr>
      <tr>
        <td>Ben McLemore</td>
        <td>SG</td>
        <td>6'5"</td>
        <td>02-11-1993</td>
        <td>$2,895,960</td>
      </tr>
      <tr>
        <td>Marcus Thornton</td>
        <td>SG</td>
        <td>6'4"</td>
        <td>05-05-1987</td>
        <td>$7,000,000</td>
      </tr>
      <tr>
        <td>Jason Thompson</td>
        <td>PF</td>
        <td>6'11"</td>
        <td>06-21-1986</td>
        <td>$3,001,000</td>
      </tr>
    </tbody>
  </table>
</div>

答案 6 :(得分:1)

我知道您只想使用CSS来实现,但是我提供了jQuery解决方案,以防有人寻求帮助。

使用jQuery,您可以获取滚动条的大小,然后在容器上应用边距。

类似这样的东西:

var code = @"
List<string> strings = new List<string>();
strings.Add(""test string"");            
return strings;";

    var options = ScriptOptions.Default
                .WithImports("System.Collections.Generic"); // chaining methods would work better here.
    // alternatively reassign the variable:
    // options = options.WithImports("System.Collections.Generic");

    var result = CSharpScript.RunAsync(code, options).Result;

    Debug.WriteLine((result.ReturnValue as List<string>).First());

如果所有内容的高度都大于容器的高度,则以上代码段将添加一个空白。

如果不需要,我们也可以删除水平滚动条:

var checkScrollBars = function(){
    var b = $('body');
    var normalw = 0;
    var scrollw = 0;
    if(b.prop('scrollHeight')>b.height()){
        normalw = window.innerWidth;
        scrollw = normalw - b.width();
        $('#container').css({marginRight:'-'+scrollw+'px'});
    }
}

答案 7 :(得分:1)

您可以“获取”并在纯CSS中使用滚动条宽度的唯一方法是实际上将滚动条放置在其中。现在,我们不想一直将滚动条强制显示为可见,因此我们要做的是: 为始终显示滚动条的网站所有内容创建一个容器,然后隐藏它。非常简单!
我已经创建了a Fiddle。这是一个片段:

/* The trick: */

html {
  overflow-x: hidden;
}

body {
  margin: 0;
  width: 100vw;
}

body > * {
  overflow-y: scroll;
  margin-right: -100px;
  padding-right: 100px;
}

/* Other styling: */

body {
  font-family: sans-serif;
  user-select: none;
  --color: rgb(255 191 191);
}

header {
  position: sticky;
  top: 0;
  z-index: 1;
  --color: rgb(191 191 255);
}

body > * > div {
  background-color: var(--color);
  border: 3px solid;
  margin: 10px;
  padding: 20px;
  font-size: 20px;
  font-weight: bold;
}

label::before {
  position: relative;
  content: '';
  display: inline-block;
  width: 1em;
  height: 1em;
  margin: 0 10px;
  top: .2em;
  border: 1px solid;
  border-radius: .1em;
}

input:checked + label::before {
  background-color: var(--color);
  box-shadow: inset 0 0 0 1px #FFF;
}

input {
  display: none;
}

input:not(:checked) ~ div {
  display: none;
}

input ~ div {
  height: 200vh;
}
<header>
  <div>I am sticky!</div>
</header>
<main>
  <div>Hello world!</div>
  <input id="foo-2" type="checkbox" />
  <label for="foo-2">Click me</label>
  <div>Let's scroll</div>
</main>

技巧是给包含的元素一个负的空白边距和右边的正填充。这两个属性所使用的偏移量可能超过滚动条的宽度,因此使其100px足够多了–我无法想象任何浏览器或网站的滚动条宽于20px,更不用说{{1} }。


顺便说一句:我将这些样式应用于100px的每个直接子级而不是拥有单个body元素的原因是,否则#container无效。要在一个元素上使用该功能,它只能具有一个具有滚动功能的祖先。

position: sticky 包含 html 包含 #container ->不起作用

sticky element 包含 html ->确实有效

答案 8 :(得分:0)

问题是,一旦将鼠标悬停在容器上并显示滚动条,则内容宽度会缩小。因此,即使您使用宽度等于容器减去其滚动条的嵌套容器,嵌套容器的宽度也将缩小。

一种解决方案是通过悬停时滚动条的宽度增加内容的大小。这是一个不需要使用任何嵌套外部容器的解决方案(categoryCont是滚动容器,每个menuBlock是要滚动的项目之一):

<div id="categoryCont" style="position:relative;width:200px; overflow:hidden;">
    <div class="menuBlock" style="width:200px">a</div>
    <div class="menuBlock" style="width:200px">b</div>
    <div class="menuBlock" style="width:200px">c</div>
    ...
</div>

<style type="text/css">
    #categoryCont:hover{
        overflow-y: auto;
    }
    #categoryCont:hover .menuBlock{
    /* Increase size of menu block when scrollbar appears */
        width: 218px;    /* Adjust for width of scroll bar. */
    }
</style>

上述问题之一是滚动条的宽度在不同的浏览器中略有不同。以下之一应该有所帮助:

  • 使用px

使用左缩进作为绝对值使内容成为绝对值

<div class="menuBlock" style="width:200px">
    a
</div>

更改为

<div class="menuBlock" style="width:200px">
    <span>a</span>
</div>

<style>
    .menuBlock span{        /* Good cross-browser solution but cannot use % */
        position:absolute;
        left:70px;
    }
</style>
  • 使用%

你需要CSS和jQuery(第一步是相同的)

<div class="menuBlock" style="width:200px">
    a
</div>

更改为

<div class="menuBlock" style="width:200px">
    <span>a</span>
</div>

<style>
    .menuBlock span{        /* Good cross-browser solution but cannot use % */
        position:absolute;  /* This one does not use 'left' */
    }
</style>

<script>
    // Indent left 30% because container width remains same but content width changes
    var leftIndent = (30/100) * $("#categoryCont").width();
    $(".menuBlock span").css({"left":leftIndent});
</script>

答案 9 :(得分:-1)

我不太确定您的要求(抱歉,我对CSS的了解很少),但是我认为您想将CSS的HTML div元素的宽度设置为100%,没有滚动条出现。这是一个解决方案。

#element {
  background-color: blue;
  height: 40px;
  position: relative;
  margin-left: 0px;
  margin-right: 0px;
  padding-left: 0px;
  padding-right: 0px;
  width: 100%;
}
<!DOCTYPE html>
<html lang="en">
  <body>
    <div id="element"></div>
  </body>
</html>

由于position元素的marginpaddingdiv属性而出现滚动条。如果将margin-rightmargin-leftpadding-rightpadding-left属性设置为0,并且将position属性设置为{{1 }},不会出现滚动条。

答案 10 :(得分:-2)

* {
    overflow: hidden;
}

隐藏滚动条的简单方法