CSS网格/布局框架,重点是固定元素和单页全屏布局 [英] CSS grid/layout framework with focus on fixed elements and single page full screen layouts

查看:729
本文介绍了CSS网格/布局框架,重点是固定元素和单页全屏布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

经验法则 - 如果你在你的布局中乱七八糟的CSS,切换到一个框架。我已经经历了几十个网格/布局框架,大部分都专注于传统的文档网格布局。

Rule of thumb - if you're messing with CSS too much in your layouts, switch to a framework. I've been going over the dozens of grid/layout frameworks out there and most of them focus on the traditional document grid layout.

我的页面更多是一个SPA单页应用)。它类似于桌面应用程序使用的布局。显然HTML不处理这个很好,需要大量的CSS修补。

My page is more of an SPA (single page application). It resembles the layout used by a desktop application. Obviously HTML doesn't handle this very well and a lot of CSS tinkering is required.

这是我想要实现的布局示例(这应该填充整个屏幕):

Here's an example of a layout I'm trying to achieve (this should fill the entire screen):

请注意,固定菜单不应该悬停在滚动内容上在他们后面。每个块应该位于自己单独的框架 - 即左侧长列表的滚动条应该出现在固定菜单下面。

Please note that the fixed menus shouldn't be hovering over the scrolling content behind them. Each block should reside in its own separate "frame" - ie the scrollbars for the long list on the left should appear below the fixed menu.

我无法找到一个支持这个框架(像Sencha或Kendo UI的轻量级网格框架有点过分)。手动执行CSS是非常费力的。特别是如果我决定显示一个模态对话框,并需要类似的布局在这个对话框(这是btw最终杀了我)。

I haven't been able to find a lightweight grid framework which supports this (frameworks like Sencha or Kendo UI are a bit of an overkill). Doing the CSS manually is very laborious. Especially if I decide to show a modal dialog box, and require similar layout inside this dialog box (this is btw what killed me eventually). Or if I decide I want another fixed menu on the bottom, all hell breaks loose.

我甚至不知道这是可能与CSS(我知道至少固定底部菜单需要CSS中的一些硬编码值,以便收缩其后面的内容,所以滚动条不重叠)。如果需要一个JS解决方案,我想要它处理浏览器屏幕调整大小的事件 - 再次所有的地狱都会松开,因为没有容易的常见事件,这是。

I'm not even sure this is possible with CSS only (I know at least fixed bottom menus require some hard-coded values in the CSS in order to shrink the content behind it so the scrollbars don't overlap). If a JS solution is required, and I want it to handle browser screen resizing events - again all hell breaks loose as there's no easy common event that does that.

如何我以可维护/灵活的方式处理这个问题?

How should I approach this in a maintainable/flexible way?

注释:您会注意到,这个布局使用HTML表。我不是真的想接受我自己的答案。我有一种感觉,没有人会勇敢足以建议表(它有争议的毕竟),我愿意为讨论的缘故遭受失望。

COMMENT: As you'll notice, I've added an answer myself suggesting to implement this layout using HTML tables. I'm not really looking to accept my own answer. I had a feeling nobody would be "brave" enough to suggest tables (it's controversial after all) and I was willing to suffer the downvotes for the sake of discussion

澄清:似乎我不够清楚,说可维护性和灵活性。我的意思是让布局妥协(即我的代表很少工作)与各种场景或需要的修改。要绝对具体,让我们提一些例子:

CLARIFICATIONS: It seems I wasn't clear enough when saying maintainable and flexible. What I mean is having the layout deal gracefully (ie with little work on my behalf) with various scenarios or required modifications. To be absolutely specific, let's mention some examples:


  1. 布局不应该介意如果它显示为一个完整的页面或内部固定模态对话框(即引导对话框)。在这些情景之间切换应该尽可能少地改变布局代码。

  1. The layout should not mind if it's displayed as a full page or inside a fixed modal dialog (ie the bootstrap dialog). Switching between these scenarios should change the layout code as little as possible.

布局应该支持多种方式来描述宽度和高度侧边栏或顶部菜单的高度)。更具体地说,应该支持以下大小调整方法:

The layout should support a multitude of ways to describe widths and heights (ie the width of a side bar or the height of the top menu). More specifically, the following sizing methods should be supported:


  • 精确的固定像素大小。

  • 相对通过使用容器的百分比来确定尺寸。例如:侧边栏宽度为整个容器(全页或对话框)宽度的30%。另一个例子:顶级菜单的高度是容器整个高度的20%(全页或对话框)。

  • 包装自己的内容。示例:顶级菜单的高度将取决于其中的内容。如果输入一行文本,它将包装而不滚动。如果您输入两行文字,它将是两倍大,并保持它们而不滚动。

  • 奖金:两个简单的组合。喜欢侧边宽度为20%但不小于50像素。

  • Exact fixed pixel size.
  • Relative sizing by using a percentage of the container. For example: side bar width is 30% of the width of the entire container (full page or dialog). Another example: top menu height is 20% Of the entire height of the container (full page or dialog).
  • Wrap around its own content. Example: the height of the top menu will depend on the content inside it. If you enter one line of text, it will wrap it without scrolling. If you enter two lines of text, it will be twice as big and hold them without scrolling.
  • BONUS: A simple combination of two. Like having a sidebar width of 20% but no less than 50 pixels.

正如Ian Clark最熟练地指出的,CSS可以实现大多数这些请求。没有任何争论。问题仍然是,如果原始CSS是最简单的使用,如果有任何可以从开发人员加载框架/另一个机制,如flexbox /表。

As Ian Clark most expertly pointed out, CSS can achieve most of these requests out of the box. There's no argument about that. The question remains if raw CSS is the simplest to use and if there's anything that can be off loaded from the developer by a framework / another mechanism like flexbox / tables.

推荐答案

更新2 (此问题似乎在演变):

Update 2 (This question seems to evolve!):

标准1 - 整页或内部模态应尽可能少更改代码

因为在这种情况下,我们的 总是100%的窗口 width / height,如果你想让你的代码很容易适应模态等,你可以总是使用 position:absolute ,因为没有任何上下文,这将是相对于正文

Because in this case the width/height of our body is always 100% of the window width/height, if you want your code to be easily adaptable to modals etc., you can always use position:absolute, as without any context this will be relative to the body.

条件2 - 布局应支持多种描述宽度和高度的方法

Criteria 2 - The layout should support a multitude of ways to describe width and heights

这里是一个JSFiddle,可以做几乎所有你提到 。它在固定元素上使用百分比和固定像素宽度。首先要注意的是,我不得不做的唯一的更改是添加一个 box-sizing:border-box 到我们的每个元素。与flexbox不同,这有很好的支持回到IE8,因此不应该导致任何问题。添加这个选项允许我们添加padding到我们的元素,而不必改变宽度来补偿。

Here's a JSFiddle that can do almost everything you mention. It uses both percentage and fixed pixel widths on the fixed elements. The first thing to note is that the only change I've had to do is add a box-sizing:border-box to each of our elements. Unlike flexbox, this has good support going back to IE8, and so shouldn't cause any issues. Adding this allows us to add padding to our elements without having to change widths to compensate.

左侧边条的宽度为20%,它们也有最小宽度为100像素。为了防止与右边主要内容的重叠,我们使用一些简单的逻辑来建立逆:

Whilst the left sidebars have a width of 20%, they also have a minimum width of 100 pixels. To prevent the overlap with the main content to the right, we use some simple logic to establish the inverse:

Reaches Min At = Min-width / Width * 100



在我们的示例中, c $ c> 100/20 * 100 = 500px 。然后,当我们达到此窗口大小时,我们使用 @media 选择器更改主内容的宽度:

In our example, our left sidebar therefore reaches a min at 100/20*100 = 500px. Then we use an @media selector to change our main content's width when we reach this window size:

@media(max-width:500px) {
  #scrolling-content { 
    left:100px;
  }
}

通过更改小提琴上的窗口大小,我们注意到,当您达到最小大小时,我们的主要内容区域会更改颜色。现在我承认,这可能看起来很混乱,但是再次,通过使用诸如Less之类的语言,你可以很容易地设置 width code>作为变量,并使用一个简单的函数来改变你的CSS。现在我使用几乎一切这个短语的原因是因为如果你想在模态中做类似的事情,这可能会更复杂,但谁知道,这是可能的!

By changing the window size on the fiddle, you'll notice that our main content area changes colour when you reach the min-size. Now I admit, this might seem confusing, but again, by using a language such as Less you could easily set the width and min-widths as variables, and use a simple function to change your CSS. Now the reason I used the phrase "almost everything" is because this could get much more complex if you wanted to do a similar thing in a modal, but who knows, it could be possible!

一个小东西要带走:如果你要使用JavaScript来调整大小调整事件,请务必考虑 jQuery debounced调整大小的插件,因为你不想要做比你需要的数百倍!

A little thing to take away: If you're ever going to use JavaScript to pick up resize events, definitely consider the jQuery debounced resize plugin as you don't want to be doing calculations hundreds of times more than you need to! I'm leaving the extra content in this answer as most is still relevant and historically accurate to your developing question

更新:有很多建议使用Flexbox的答案,但我真的不认为这是一个很好的解决方案。不要误会我,如果FlexBox是一个真正可行的解决方案,我会喜欢它,但在分钟 支持他们是可怕的 ,如果你要为大多数网络polyfill,那么,你可能会使用任何其他JavaScript解决方案,我不认为JavaScript是

Update: There's a lot of answers suggesting using Flexboxs, but I really don't think that's a great solution at the minute. Don't get me wrong, I'd love it if FlexBox's were a really viable solution, but at the minute Support for them is terrible, and if you're going to polyfill it for the majority of the web then, you might as well be using any other JavaScript solution, and I don't think JavaScript is the right tool to use for the entire presentation of your page.

仍然不明白为什么您的目标难以实现使用简单的CSS position s。你不需要使用任何JavaScript和。我认为 非常易于管理。如果您真的难以维护样式表,那么为什么不使用 Sass / SCSS 较少 ,因为您可以创建变量,混合,函数等,并显着减少所需的更改数量make。

I still don't see why your goals are hard to achieve using simple CSS positions. You don't need to use any JavaScript and. I'd argue that it is very manageable. If you're really struggling with maintaining your stylesheets, then why not use something like Sass/SCSS or Less, as you could then create variables, mixins, functions etc., and significantly reduce the number of changes you need to make.

也就是说, 他是一个真正快速模型的解决方案 ,只使用纯CSS和HTML。我使用的是4固定的 div ,可以做一个简单的修改,使滚动内容不是固定的,但只是使用边距正确定位。

That said, he's a really quick mockup of your solution, working using just pure CSS and HTML. All I'm using is 4 fixed divs, and a simple modification could be made so that the "scrolling content" is not fixed, but just uses margins to be positioned correctly. That would have the added bonus of not having to scroll within the div, but being able to do so against the body.

所有需要的CSS:

div { position:fixed; }
#top {
    top:0;
    left:0;
    right:0;
    height:40px;
}

#menu {
    top:40px;
    height:40px;
    left:0;
    width:200px;
}

#long-list {
    top:80px;
    left:0;
    width:200px;
    bottom:0;
    overflow-y:auto;
}
#scrolling-content {
    top:40px;
    bottom:0;
    right:0;
    left:200px;
    overflow-y:auto;
}

很容易注意到 40px 200px 作为菜单的高度和宽度。考虑到这一点,你可以简单地使用动态语言的变量,并只定义它们一次(更少的例子):

It's pretty easy to note the repetition of 40px and 200px as the height and width of the menus. With that in mind, you could simply use a dynamic language's variable and define them only once (Less example):

@leftwidth: 200px;

#scrolling-content {
    left:@leftwidth;
}
#menu, #longlist {
    width:@leftwidth;
}



争议#1:框架不灵活或易于编辑



你提到很难轻易地操纵CSS框架,因为依赖于静态内容,他们必须决定要使用的列数(在Bootstrap和许多其他情况下12,因为它很容易被1,2,3,4,6整除)。 ,在Bootstrap 2中,很容易自定义列数。当Bootstrap 3 RC2弹出时,此功能也存在。还有许多资源允许您使用 Less with Bootstrap 。也就是说,创建一个低风格的柔性流体网格系统是相当常见的,见演示(免责声明:我没有经验with Less,本文帮助我进行循环):

Dispute #1: Frameworks aren't flexible or easy to edit

You mentioned that it's difficult to easily manipulate CSS frameworks, as relying on static content, they have to make decisions over the number of columns to use (in Bootstrap and many other cases they choose 12 as it's easily divisible by 1,2,3,4,6). However, in Bootstrap 2, it's very easy to customise the number of columns. Expect this feature to also exist when Bootstrap 3 RC2 comes out. There are also many resources which allow you to use Less with Bootstrap. That said, it would be fairly routine to create a Less-style flexible fluid-grid system, see demo (Disclaimer: I have no experience with Less, this article helped me with looping):

/* The total number of columns you wish to use */
@columns: 15;
/* 
    We loop through and for each create class
   .dynamic-<index>-<columns> 
*/
 .looping (@index) when (@index > 0) {
    (~".dynamic-@{index}-@{columns}") {
        width: percentage(@index/@columns);
    }
    .looping(@index - 1);
}
/* Stop and do nothing at 0 */
.looping (0) {}
/* Call our function */
.looping (@columns);

然后你的HTML标记就变成了:

And then your HTML markup simply becomes:

<div class="cf rows">
    <div class="dynamic-4-15">4/15th width</div>
    <div class="dynamic-7-15">7/15th width</div>
</div>



争议2:使用CSS难以使用基于百分比的模式



在你提到的注释中,你希望布局是相对于对话框宽度,而不是浏览器窗口宽度。这当然是可能的。事实上,这很容易, 并且几乎不需要更改我们的代码

Dispute #2: Percentage-based modals are difficult using CSS

In the comments you mentioned that you "would want the layout to be relative to the dialog width, not the browser window width". Well that's certainly possible too. In fact, it's really easy, and requires almost no change to our code:

#some-modal {
   position:fixed;
   top:10%;
   bottom:10%;
   left:10%;
   right:10%;
}
/* Before this was simply div, and it was fixed, now it's absolute */
#some-modal div {
   position:absolute;
   padding:10px;
}

这篇关于CSS网格/布局框架,重点是固定元素和单页全屏布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆