Introdução

Esta documentação detalha as diferenças no cálculo de dimensões dos componentes entre o SmartClient Desktop e o WebApp.

A principal diferença está no tratamento da margem (  margin ) no desktop, ela é considerada no cálculo do layout, enquanto no WebApp, devido às características nativas dos navegadores.

Essas diferenças de comportamento já eram esperadas entre o SmartClient Desktop e o SmartClient WebApp, devido às particularidades de cada plataforma.

Diferenças entre Deskop e WebApp

Desktop


No Smartclient Desktop, as margens são incluídas no cálculo do layout dos componentes. Isso significa que o espaço disponível dentro de um componente é reduzido conforme as margens aplicadas, pois elas fazem parte da dimensão total do elemento.

WebApp


No WebApp, é utilizado a propriedade box-sizing: border-box , que inclui o padding e a borda no cálculo da largura e altura. No entanto, a margem (margin) não é considerada, pois ela não faz parte do elemento em si, mas sim do espaço ao seu redor.

Além disso, incluir a margem nos cálculos de layout no WebApp resultaria em uma perda significativa de performance, especialmente em layouts mais dinâmicos, motivo pelo qual essa abordagem não foi adotada.

Solução Recomendada

Para garantir um comportamento mais consistente entre os sistemas, recomendamos a utilização de componentes baseados em FlexBox, como:

Esses componentes gerenciam automaticamente o espaçamento interno e externo, oferecendo um comportamento que melhor se aproxima do SmartClient Desktop, descontando a margem do cálculo total do layout.

Exemplo de Implementação

Utilizando TLinearLayout e aplicando estilos CSS
   	#Include "totvs.ch"
	#define LAYOUT_LINEAR_L2R 0 // LEFT TO RIGHT
	#define LAYOUT_LINEAR_R2L 1 // RIGHT TO LEFT
	#define LAYOUT_LINEAR_T2B 2 // TOP TO BOTTOM
	#define LAYOUT_LINEAR_B2T 3 // BOTTOM TO TOP

	#define LAYOUT_ALIGN_LEFT     1
	#define LAYOUT_ALIGN_RIGHT    2
	#define LAYOUT_ALIGN_HCENTER  4
	#define LAYOUT_ALIGN_TOP      32
	#define LAYOUT_ALIGN_BOTTOM   64
	#define LAYOUT_ALIGN_VCENTER  128

user function clcLinear()
	local cCSS			:= ""

	oWnd:= TWindow():New(0, 0, 500, 400, "TAlignLayout Aninhado", NIL, NIL, NIL, NIL, NIL, NIL, NIL, CLR_BLACK, CLR_WHITE, NIL, NIL, NIL, NIL, NIL, NIL, .T. )

	oBodyLyt := tLinearLayout():New(oWnd, LAYOUT_LINEAR_T2B, CONTROL_ALIGN_ALLCLIENT, 0, 0)
	cCSS				:=	"QWidget { "
	cCSS				+=		"background-color: #17a2b8;"
	cCSS				+=		"border: 1px solid #000000; "
	cCSS				+=		"border-radius: 4px;"
	cCSS				+=		"padding: 10px;"
	cCSS				+=	"} "
	oBodyLyt:SetCSS(cCSS)
	oPanel01 := tPanel():New(0,0,,oBodyLyt,,.T.,,,CLR_LIGHTGRAY,0,0)
	cCSS				:=	"QWidget { "
	cCSS				+=		"background-color: #e8dba2; "
	cCSS				+=		"border: 1px solid #000000; "
	cCSS				+=		"margin: 0 10px 10px 0; "
	cCSS				+=		"border-radius: 4px; "
	cCSS				+=		"padding: 10px;"
	cCSS				+=	"} "
	oPanel01:SetCSS(cCSS)
	oPanel02 := tLinearLayout():New(oBodyLyt, LAYOUT_LINEAR_L2R, CONTROL_ALIGN_ALLCLIENT, 0, 0)
	cCSS				:=	"QWidget { "
	cCSS				+=		"background-color: #a2e8d5; "
	cCSS				+=		"border: 1px solid #000000; "
	cCSS				+=		"margin: 0 10px 10px 0; "
	cCSS				+=		"border-radius: 4px; "
	cCSS				+=		"padding: 10px;"
	cCSS				+=	"} "
	oPanel02:SetCSS(cCSS)
	oPanel03 := tPanel():New(0,0,,oBodyLyt,,.T.,,,CLR_BROWN,0,0)
	cCSS				:=	"QWidget { "
	cCSS				+=		"background-color: #b9a2e8; "
	cCSS				+=		"border: 1px solid #000000; "
	cCSS				+=		"margin: 0 10px 10px 0; "
	cCSS				+=		"padding: 10px;"
	cCSS				+=		"border-radius: 4px; "
	cCSS				+=	"} "
	oPanel03:SetCSS(cCSS)

	oBodyLyt:addInLayout(oPanel01,,33)
	oBodyLyt:addInLayout(oPanel02,,33)
	oBodyLyt:addInLayout(oPanel03,,33)

	oPnel01 := tPanel():New(0,0,,oPanel02,,.T.,,,CLR_YELLOW,0,0)
	cCSS				:=	"QWidget { "
	cCSS				+=		"background-color:rgb(232, 162, 177); "
	cCSS				+=		"border: 1px solid #000000; "
	cCSS				+=		"margin: 0 10px 10px 0; "
	cCSS				+=		"padding: 10px;"
	cCSS				+=		"border-radius: 4px; "
	cCSS				+=	"} "
	oPnel01:SetCSS(cCSS)
	oPnel02 := tPanel():New(0,0,,oPanel02,,.T.,,,CLR_BLUE,0,0)
	cCSS				:=	"QWidget { "
	cCSS				+=		"background-color:rgb(162, 232, 165); "
	cCSS				+=		"border: 1px solid #000000; "
	cCSS				+=		"margin: 0 10px 10px 0; "
	cCSS				+=		"padding: 10px;"
	cCSS				+=		"border-radius: 4px; "
	cCSS				+=	"} "
	oPnel02:SetCSS(cCSS)
	oPnel03 := tPanel():New(0,0,,oPanel02,,.T.,,,CLR_GREEN,0,0)
	cCSS				:=	"QWidget { "
	cCSS				+=		"background-color:rgb(217, 232, 162); "
	cCSS				+=		"border: 1px solid #000000; "
	cCSS				+=		"margin: 0 10px 10px 0; "
	cCSS				+=		"padding: 10px;"
	cCSS				+=		"border-radius: 4px; "
	cCSS				+=	"} "
	oPnel03:SetCSS(cCSS)

	oPanel02:addInLayout(oPnel01,,33)
	oPanel02:addInLayout(oPnel02,,33)
	oPanel02:addInLayout(oPnel03,,33)
	oWnd:Activate("MAXIMIZED")
return


Essa abordagem permite que o espaço entre os elementos seja controlado de forma eficiente.

Conclusão

A diferença no tratamento das margens entre Desktop e WebApp é uma decisão arquitetural voltada para otimizar o desempenho no ambiente web.
Embora essa abordagem possa resultar em pequenas diferenças visuais entre os dois sistemas, o uso adequado dos componentes como TGridLayout, TLinearLayout e TFlowLayout, ajuda a minimizar esses impactos e garantir um comportamento mais consistente e previsível.

  • Sem rótulos