合并百分比+像素div布局

时间:2013-07-01 11:28:12

标签: javascript css html layout

10年前我用C ++编写了一个GUI布局引擎,我很好奇它的功能如何在浏览器中最接近。

1。 C ++

在较旧的GUI库(如Microsoft Windows')中,小部件的位置和大小通常由四个数字给出: left,top,width 和< EM>高度。我的引擎不同之处在于每个数字都加倍,所以你必须指定八个数字:相对左,绝对左;相对顶部,绝对顶部;相对宽度,绝对宽度;相对高度绝对高度相对值应以父窗口小部件的宽度或高度的百分比给出,绝对值应在中给出像素即可。对于顶级窗口,“父窗口小部件”是桌面。

示例:

a)400 x 300 px窗口,以屏幕为中心:

const int WINDOW_WIDTH = 400;
const int WINDOW_HEIGHT = 300;
CWindow mainWindow;
mainWindow.setPosition(0.5, -WINDOW_WIDTH / 2, 0.5, -WINDOW_HEIGHT / 2); 
mainWindow.setSize(0.0, WINDOW_WIDTH, 0.0, WINDOW_HEIGHT);

b)主窗口右边缘的150 px宽按钮容器面板:

const int PANEL_WIDTH = 150;
CPanel buttonPanel(mainWindow);
buttonPanel.setPosition(1.0, -PANEL_WIDTH, 0.0, 0); 
buttonPanel.setSize(0.0, PANEL_WIDTH, 1.0, 0);

c)容器面板顶部有三个按钮(新建,打开,保存),底部有一个按钮(退出):

const int BUTTON_HEIGHT = 30;
CButton newButton(buttonPanel, "New");
newButton.setPosition(0.0, 0, 0.0, 0 * BUTTON_HEIGHT);
newButton.setSize(1.0, 0, 0.0, BUTTON_HEIGHT);
CButton openButton(buttonPanel, "Open");
openButton.setPosition(0.0, 0, 0.0, 1 * BUTTON_HEIGHT);
openButton.setSize(1.0, 0, 0.0, BUTTON_HEIGHT);
CButton saveButton(buttonPanel, "Save");
saveButton.setPosition(0.0, 0, 0.0, 2 * BUTTON_HEIGHT);
saveButton.setSize(1.0, 0, 0.0, BUTTON_HEIGHT);
CButton exitButton(buttonPanel, "Exit");
exitButton.setPosition(0.0, 0, 1.0, -1 * BUTTON_HEIGHT);
exitButton.setSize(1.0, 0, 0.0, BUTTON_HEIGHT);

手工编写这样的布局代码可能会让您感到尴尬,但是一旦掌握了它就很容易。

2。 HTML,CSS,JavaScript

到目前为止,

Here是我能够共同破解的:

a)主窗口,按钮面板和按钮的层次结构以HTML格式显示:

<div id="mainWindow">
    <div id="buttonPanel">
        <div id="newButton" class="button"></div>
        <div id="openButton" class="button"></div>
        <div id="saveButton" class="button"></div>
        <div id="exitButton" class="button"></div>
    </div>
</div>

b)在CSS中div的位置设置为绝对值:

* {
    -webkit-box-sizing: border-box; 
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
body { margin: 0; color: yellow; }
#mainWindow { position: absolute; background: red; }
#buttonPanel { position: absolute; background: green; }
.button { border: 1px solid cyan; }
#newButton { position: absolute; background: blue; }
#openButton { position: absolute; background: blue; }
#saveButton { position: absolute; background: blue; }
#exitButton { position: absolute; background: blue; }

c)布局功能在JavaScript中实现,使用jQuery:

function setPosition(widget, relLeft, absLeft, relTop, absTop) {
    $(widget)
        .css('left', relLeft * 100 + '%').css('left', '+=' + absLeft + 'px')
        .css('top', relTop * 100 + '%').css('top', '+=' + absTop + 'px');
}

function setSize(widget, relWidth, absWidth, relHeight, absHeight) {
    $(widget)
        .css('width', relWidth * 100 + '%').css('width', '+=' + absWidth + 'px')
        .css('height', relHeight * 100 + '%').css('height', '+=' + absHeight + 'px');
}

function setButtonText(button, text, height) {
    $(button)
        .text(text)
        .css('text-align', 'center')
        .css('vertical-align', 'middle')
        .css('line-height', height + 'px');
}

window.onresize = function () {
    var WINDOW_WIDTH = 400,
        WINDOW_HEIGHT = 300,
        PANEL_WIDTH = 150,
        BUTTON_HEIGHT = 30;

    setPosition('#mainWindow', 0.5, -WINDOW_WIDTH / 2, 0.5, -WINDOW_HEIGHT / 2);
    setSize('#mainWindow', 0.0, WINDOW_WIDTH, 0.0, WINDOW_HEIGHT);
    setPosition('#buttonPanel', 1.0, -PANEL_WIDTH, 0.0, 0);
    setSize('#buttonPanel', 0.0, PANEL_WIDTH, 1.0, 0);
    setButtonText('#newButton', "New", BUTTON_HEIGHT);
    setPosition('#newButton', 0.0, 0, 0.0, 0 * BUTTON_HEIGHT);
    setSize('#newButton', 1.0, 0, 0.0, BUTTON_HEIGHT);
    setButtonText('#openButton', "Open", BUTTON_HEIGHT);
    setPosition('#openButton', 0.0, 0, 0.0, 1 * BUTTON_HEIGHT);
    setSize('#openButton', 1.0, 0, 0.0, BUTTON_HEIGHT);
    setButtonText('#saveButton', "Save", BUTTON_HEIGHT);
    setPosition('#saveButton', 0.0, 0, 0.0, 2 * BUTTON_HEIGHT);
    setSize('#saveButton', 1.0, 0, 0.0, BUTTON_HEIGHT);
    setButtonText('#exitButton', "Exit", BUTTON_HEIGHT);
    setPosition('#exitButton', 0.0, 0, 1.0, -1 * BUTTON_HEIGHT);
    setSize('#exitButton', 1.0, 0, 0.0, BUTTON_HEIGHT);
};

onresize();

请注意,JavaScript代码与上面显示的C ++代码非常相似!

我的问题

这个基于JavaScript的布局是否可以构建“真正的”Web应用程序,或者我应该使用CSS代替?由于我基本上是桌面应用程序开发人员,因此需要专家级Web开发人员的意见。谢谢!

===更新===

Here是纯HTML + CSS解决方案。我使用了@Christoph提出的负边距技巧。我唯一的问题是相同的常量被复制到CSS中的很多地方。例如,按钮高度(30px)用于九个位置,这使维护更加困难。

4 个答案:

答案 0 :(得分:4)

通常,内联css(通过style=""附加的css)被认为是一个糟糕的选择。由于您通过脚本动态生成它,因此可以接受。

然而,有一些问题:

  1. 一般来说,绝对定位应尽量少用。
  2. 绝对不需要改变window.onresize中的布局。应谨慎使用此事件。正如您在小提琴中看到的那样,您的示例UI相当小,但在调整窗口大小时已经变得无法响应。 (无论如何,你的例子中的那些值都是静态的)
  3. 所以我的提示是:

    1. 使用某种init()方法进行初始布局
    2. 避免window.onresize或至少使用一些超时机制来减少触发那些绘画事件(reduce number of calls for .resize and .scroll methods
    3. 也许不是jQuery的css()调用,而是在separate stylesheet中为你的元素编写css。
    4. 最佳解决方案:生成html和css标记服务器端,并将最终的html + css提供给浏览器。优点:更快的渲染+可维护+你得到一个可缓存的样式表和html

答案 1 :(得分:2)

使用CSS设置初始值总是更容易,性能更好,更快。将所有内容设置为绝对可以工作,但是,根据应用程序,可能会成为布局噩梦,因为绝对定位的元素将从正常流中移除。

虽然我看到你来自哪里,曾经为桌面编写图形应用程序,你会发现它对网络效果不佳,除非你期望一个固定的布局,其中布局性能不是是至关重要的。

然而,我正在思考当今世界的布局,你需要适应各种形状和大小的设备。一方面,使用javascript可以更容易地控制所有这些,并且很多时候它是最好的方式,但是,otoh,CSS可以处理大量的媒体查询,以减轻您和编码的负担。 / p>

要考虑很多。

答案 2 :(得分:2)

简短回答:

这太糟糕了!永远不要那样。

答案很长:

这不是网络的工作方式。您的应用程序将无法执行,因为css规则将等待js下载和解释;但这不是这里的主要问题。主要关注的是你。

您永远无法维护像这样的代码。当您构建一个简单的应用程序时,您可以轻松地使用几千个css规则。如果以这种方式组织,则无法阅读。我甚至没有提到媒体查询的东西。以这种方式构建应用程序的复杂性太高了。

如果你想去网络,你必须拥抱网络;不要尝试旧的桌面应用程序开发技巧(这是桌面应用程序的优点)。例如,如果您想在右上角放置一些内容,请转到:right: 0。不是WINDOW_WIDTH;如果你的蚂蚁集中在某些地方,你有很多方法可以这样做;但是你没有为这个职位做数学。从来没有这样做过。


作为一个webapplication开发者,我的建议就是这个:

使用罗盘:http://compass-style.org/

其实不行,请使用Yeoman:http://yeoman.io/

使用工具有点复杂,无法完全理解;但它太值得了。


顺便说一句,永远不要绑定onresize这样的事件。您必须添加debounce,否则您将遇到严重的表演麻烦。

答案 3 :(得分:1)

我绝对不是专家,但这是我的2美分:

在您的设计中使用JavaScript一直很好。但是为了做到这一点,你还需要一些静态CSS,对于那些没有启用JavaScript的人来说,还有可访问性等等。

Javascript设计一直是关于增强您的Web应用程序,而不是替换它。你绝对应该看一下关于Unobtrusive JavaScript的维基百科页面。

回到你的问题,为什么不默认你的按钮有一个固定的大小,让你的JavaScript功能在可用时替换它?

此外,我在您的Web应用程序中没有得到的是,在这里,一切都可以在CSS中完成,并且速度更快。它会有更好的性能,你甚至不用担心JavaScript。