diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000000..ed72ce1e0f --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,51 @@ +# Simple workflow for deploying static content to GitHub Pages +name: Deploy website content to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["main", "feat/website"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Single deploy job since we're just deploying + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Pages + uses: actions/configure-pages@v3 + - uses: actions/setup-node@v2 + with: + node-version: "18.12.1" + - name: Build the Docs + run: | + cd website + npm i + npm run build + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + # Upload entire repository + path: './website/build' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000000..b2d6de3062 --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/website/README.md b/website/README.md new file mode 100644 index 0000000000..aaba2fa1e1 --- /dev/null +++ b/website/README.md @@ -0,0 +1,41 @@ +# Website + +This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. + +### Installation + +``` +$ yarn +``` + +### Local Development + +``` +$ yarn start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. + +### Build + +``` +$ yarn build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +### Deployment + +Using SSH: + +``` +$ USE_SSH=true yarn deploy +``` + +Not using SSH: + +``` +$ GIT_USER= yarn deploy +``` + +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/website/babel.config.js b/website/babel.config.js new file mode 100644 index 0000000000..e00595dae7 --- /dev/null +++ b/website/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/website/docs/resources/design_documents.md b/website/docs/resources/design_documents.md new file mode 100644 index 0000000000..70e5b9f296 --- /dev/null +++ b/website/docs/resources/design_documents.md @@ -0,0 +1,347 @@ +--- +sidebar_position: 1 +title: Design Documents +--- + +## Introduction + +When developing a mobile application, considerations around development efficiency, performance & user experience, and +maintenance iteration costs are unavoidable. + +Apps based on WebView can offer excellent development efficiency. However, their performance and user experience are +typically mediocre. They also suffer from compatibility issues due to browser fragmentation and have inconvenient +debugging, leading to increased maintenance and iteration costs. + +Pure client-side development technologies based on Native/Flutter can provide the best performance and user experience. +However, their development efficiency lags behind Web, and they're limited by release constraints, meaning that their +iteration cycles are strictly controlled, failing to respond to business demands in real-time. + +WebF is a rendering engine compatible with web browsers. It builds upon Flutter's existing rendering pipeline and +implements the capabilities that web applications depend on, such as CSS/HTML/JavaScript/Web API. This allows +applications written by front-end developers to run on Flutter. + +WebF offers developers a development efficiency comparable to WebView. Simultaneously, its performance and experience +lie between WebView and Native apps. It provides developers with a consistent runtime environment across all platforms, +eliminating concerns about compatibility. It also supports debugging using Chrome's DevTools and even has the capability +to perform real-time debugging of all functionalities in a production environment, significantly reducing the cost of +application maintenance and iteration. + +In terms of performance and experience, WebF also offers developers two different solutions to cater to various business +scenarios. Developers can freely choose to use CSS directly or employ Flutter Widget for UI implementation. The former +has a lower development maintenance cost, while the latter delivers a better interaction and experience. + +## Architecture Overview + +![1](./imgs/architecture_overview.png) + +WebF, built upon Flutter Foundation, has additionally constructed a Rendering layer to implement layout capabilities as +defined in the CSS standard, including Flexbox, Flow layouts, positioning, etc., to cater to developers' needs to design +various page layouts using CSS. + +Furthermore, it integrates the parsing of HTML and CSS, the construction of the DOM tree, the building of the CSSOM, and +the processing of cascading styles, catering to developers utilizing HTML to establish page structure and CSS cascade +style sheets to set the page's appearance. The HTML/CSS capabilities provided by WebF are all implemented as defined by +the W3C standard and compatible to web browsers. The final result is entirely consistent with the outcome rendered by +browsers like Chrome and Safari. This allows developers to run HTML/CSS codes written for the web directly on WebF +without any modifications, eliminating the need to learn new functionalities. By mastering web development technologies, +developers can effortlessly develop applications on WebF. + +Beyond the core HTML/CSS capabilities, WebF also offers auxiliary features such as Web Modules and Inspector to provide +developers with extensibility and debugging support. + +The capabilities described above detail the core rendering support that WebF achieves based on Flutter using the Dart +language. To enable developers to construct pages using JavaScript, WebF incorporates QuickJS as its JavaScript Engine +and integrates commonly used Web APIs and DOM APIs in web pages, fulfilling the operational requirements for frontend +frameworks like React and Vue. This ensures that these frontend frameworks and their related ecosystem components run in +the JavaScript environment provided by WebF without altering a single line of code, achieving a seamless migration from +web pages to WebF pages. + +## The Rendering Process of WebF + +![image-20231016083451148](./imgs/rendering_process.png) + +The HTML/CSS/JavaScript written by developers undergoes six stages to render the codes into pixels and display them on +the user's mobile device: + +1. **Parsing**: HTML Parser and CSS Parser are used to generate the respective DOM Tree and CSSOM Tree. +2. **JavaScript Execution**: The JavaScript Engine parses and runs the code. During this phase, the frontend framework's + code will be executed. Additionally, the structure of the DOM Tree might be modified and updated through JavaScript + APIs. +3. **Tree Combination**: The DOM Tree and CSSOM Tree are combined to form the RenderObject Tree. +4. **Layout**: The hardware notifies the software layer through the VSYNC signal. As the next frame for rendering + begins, the Layout method of the RenderObject Tree is sequentially invoked. This confirms the entire page's structure + and coordinate information. The internal layout algorithm will convert the style information passed by the user + through the CSS stylesheet into corresponding dimensions and coordinates, establishing the position of every + RenderObject on the page. +5. **Painting**: Once the layout for the RenderObject is finalized, it transitions into the Paint phase. In this phase, + the RenderObject interprets the styling information set through the CSS stylesheet into corresponding graphic API + drawing commands. Leveraging dimensions and coordinates acquired from the preceding stage, it then converts these + drawing commands into the Layer Tree, which is subsequently relayed to the Flutter engine. +6. **Rendering & Display**: Upon receiving the Layer Tree, the Flutter engine employs Skia/Impeller to transmute the + graphic commands into corresponding operations for OpenGL/Metal/Vulkan. These operations are then processed by the + GPU, culminating in the content being displayed on the user's screen. + +## The Binding System of WebF + +WebF utilizes the QuickJS JavaScript Engine, developed by Fabrice Bellard. QuickJS supports the ES2020 specification, +encompassing features such as modules, asynchronous generators, proxies, and BigInt. + +However, standard JavaScript engines, including QuickJS, don't natively support Web API interfaces like Window, +Document, and DOM APIs. These interfaces are defined in W3C/WhatWG standards and are typically exclusive to JavaScript +runtimes in web browsers. + +To bridge this gap, WebF's binding system was conceived. Its primary function is to seamlessly integrate APIs from +C++/Dart DOM implementations into the JavaScript environment. + +A significant portion, nearly half, of WebF's codebase is written in Dart. Additionally, WebF leverages the Flutter +widget system. This setup allows Flutter developers to craft custom elements using Flutter widgets and Dart. Given that +the custom elements are wholly defined in Dart, the binding system also facilitates a mechanism that defines properties +and methods in Dart, ensuring they are accessible in JavaScript. + +They are hundreds of Web API was included in WebF; These APIs meet the execution requirements of front-end frameworks +and application codes. + +These built-in APIs are implemented using C++. They are then exposed as JavaScript APIs through the C API provided by +the QuickJS Engine for JavaScript to call. + +However, to fully expose a comprehensive set of C++ implemented DOM API and Web API for JavaScript to call, we need a +complete registration management mechanism to assist core developers in maintaining these APIs. + +### How JavaScript Web APIs Registered in WebF + +The Web APIs defined by W3C web standards are not just standalone sets of APIs. They are organized into an extensive +prototype chain where each member can inherit the properties and methods of its parent. JavaScript uses prototype +objects to implement class inheritance. + +QuickJS provides only the fundamental atomic operation C APIs for developers, such as creating an object, setting an +attribute, and defining an object's prototype, among others. However, according to the WhatWG DOM standard, a +comprehensive DOM API encompasses EventTarget, Node, Element, HTMLElement, and the various HTML tags corresponding to +HTMLElement. They have an inheritance hierarchy: Node inherits from EventTarget, Element inherits from Node, and +HTMLElement inherits from Element. With each level of inheritance, the derived class inherits all the properties and +methods of its parent class. + +Given that we have a collection of EventTarget, Node, and Element implemented in C++, how can we make them available in +JavaScript? The challenge is to ensure that performance isn't compromised while maintaining the inheritance +relationships from C++. + +If JavaScript retrieves a DOM object, these inheritance relationships must be pre-established. This allows users to +utilize JavaScript to access properties and methods defined by the Element from this object, as well as those defined by +EventTarget. + +When aiming to implement a comprehensive set of DOM APIs in C++, the primary challenge is establishing the inheritance +of properties and methods. This ensures that an Element instantiated in C++ can access methods delineated on the +EventTarget, which is also crafted in C++ + +![image3](./imgs/api_organized.png) + +JavaScript employs the prototype mechanism to achieve property inheritance, a mechanism that can be extended to objects +instantiated in C++. By utilizing the QuickJS API to adjust the prototype chain of objects created in C++, we can +establish their inheritance relationships. Consequently, JavaScript code can navigate and locate the relevant properties +and methods via the prototype chain + +#### How to Implement Type Mapping between C++ and JavaScript + +JavaScript is a dynamically typed language, so converting its types to C++ requires runtime checks to ascertain the +exact type of a parameter. When C++ receives a call from JavaScript, there has to be a preliminary logic check before +the type conversion can occur. + +Thanks to TypeScript typing, we can know the expected parameter types for an API. This can enable us to generate logic +checks for automatic type conversion and verification. However, due to the countless combinations of JavaScript types, +simple "if" checks cannot cover every scenario. We need a mechanism that can handle combinations of different types and +also validate these types. + +WebF uses the C++ Template Type Traits feature to implement this type conversion module. + +![image6 (1)](./imgs/gen_bindings.png) + +The code generator uses TypeScript Typings' type definitions to produce the relevant type conversion code. The Converter +is a C++ template class designed to accept template parameters. The code generator transposes the TypeScript type into +template parameters that the Converter can process, enabling the Converter to manage type validation and associated +operations. + +Specific type mapping is as follows: + +| TS | C++ | +|-------------------------------------------------|--------------------------| +| double | IDLDouble | +| Int64 | IDLInt64 | +| double? | `IDLOptional` | +| double \| null | `IDLNullable` | +| double[] | `IDLSequence` | +| type BlobParty = { name: string, value: double} | DictionaryType | +| Function | const std::shared_ptr< > | +| any | IDLAny | + +The C++ Template's Type Traits will automatically match the corresponding class based on the template parameter and then +call the processing function corresponding to the type: + +![img](./imgs/binding_code.png) + +#### How to Quickly Generate the Type Mapping and API codes + +The DOM API and Web API standards encompass a vast array of APIs and attributes, collectively numbering in the hundreds. +Each attribute has its specific parameters and type constraints. In WebF, these APIs have C++ implementations. To make +them accessible to JavaScript, they need to be wrapped using the QuickJS API, complete with parameter validation. +Manually coding this would be not only tedious but also prone to human error. Hence, the logical approach is to employ a +specialized code generator to expedite the creation of the Binding API code. + +img + +The DOM API and Web API standards define a large number of APIs and attributes, which combined, total in the hundreds. +Each attribute has its corresponding parameters and type requirements. In WebF, these APIs are implemented using C++. +However, invoking the QuickJS API is essential to encapsulate these C++ functions into a JavaScript function for +JavaScript calls, along with the necessary parameter validation. Manually writing this vast amount of code would not +only be time-consuming but might also lead to errors due to individual oversight. Thus, hand-writing this code would +result in a significant waste of time and resources. As a result, there's a pressing need to develop a specialized code +generator that can rapidly generate Binding API code. + +code_gen + +Using the Compiler API provided by TypeScript, the Code Generator parses the TypeScript Types into a TypeScript AST. +Then, through a series of transformations, it generates the IDLBlobs data structure. IDLBlobs represents the structured +information of TypeScript Types and can be read by the EJS Template to generate C++ files. During the generation +process, code for parameter validation is also produced. This validation ensures that JavaScript types are correctly +converted to C++ types for use in C++ code. + +### How to achieve high-performance data communication between C++ and Dart + +WebF's built-in JavaScript Engine, DOM API, and Web API are all implemented in C/C++. However, the specific +implementations of DOM and CSS, as well as layout-related capabilities, are written in the Dart language. Therefore, +establishing a high-performance data channel is a necessary step. + +#### Relationship between JavaScript and Dart threads + +In the design of some rendering engines, they tend to place JavaScript and UI rendering in separate, independent +threads. This design offers the benefit of ensuring that the execution of JavaScript and the rendering of the UI don't +interfere with each other. However, since JavaScript and UI run on two separate threads, their data communication must +be managed through thread scheduling and synchronization. Therefore, whenever data communication occurs, it +simultaneously affects the performance of both threads, causing the entire page to lag + +![dart_js_thread](./imgs/dart_js_thread.png) + +When developers need to implement UI animations in a page using JavaScript, they face a noticeable frame drop issue. The +root cause of this problem is that since JavaScript controls the UI for animations, there needs to be communication from +JavaScript to UI and vice versa during the rendering process of every frame. To achieve a rendering frame rate of at +least 60 FPS, the time consumed per frame must be less than 16 ms. However, for rendering engines that treat JavaScript +and UI threads as two separate entities, this time is far from sufficient, leading to stuttering issues. + +![single_thread](./imgs/single_thread.png) + +In WebF, JavaScript and Dart run in the same thread, eliminating the need for multi-thread synchronization. Furthermore, +benefiting from the single-threaded model, Dart and C++ can share data. This allows for more efficient information +communication than conventional data structures like JSON. + +#### Design of DOM Node Operation Command Buffer + +During the initial page load phase, the rendering engine needs to parse HTML and generate a large number of DOM nodes. +The creation information of these nodes needs to be sent from C++ to Dart, and then handed over to the Dart side to +complete the remaining steps. + +Typically, this information is very dense at initial load. Even simpler web applications can produce thousands of DOM +operation instructions. Due to the communication efficiency of Dart FFI, a single Dart FFI to C++ communication takes +about 0.01 to 0.02 ms. Therefore, for such dense communication instruction operations, it is necessary to buffer the +operations and then process them in batches. + +![command_buffer](./imgs/command_buffer.png) + +At the start of each frame, when there is JavaScript code to execute, and the DOM API is manipulated through JavaScript, +a UICommand operation instruction is generated. The generated operation instructions are not sent to Dart immediately +but are stored in a separate space. + +As the frame is about to end, all cached UICommands are retrieved at once, and operations are executed in bulk. Finally, +ClearUICommand is called to clear the instructions, awaiting the next frame's processing. + +#### Data communication format of DOM node operation Command + +To maximize performance, WebF has specifically designed a special command format for DOM node operations: + +ui_command + +The single UICommand is 40 bytes, with both Type and ID taking up 4 bytes each, Arg0_len and Arg1_len are also 4 bytes +each, and the remaining members are 8 bytes each. + +This data structure, simply by reading memory in 40-byte lengths, allows the retrieval of multiple operation commands. +There's no need for additional parsing; they can be used directly. + +This design is very efficient because it minimizes the overhead of command processing, allowing for a streamlined, +low-latency communication between C++ and Dart. The fixed size of commands simplifies the reading process, eliminating +the need for complex parsing logic or handling of variable-length messages. + +#### Data communication format specifically designed for APIs + +Besides using UICommand, WebF also provides a way for JavaScript to communicate data directly with Dart through C++. + +In WebF, JS needs to send various types of data to the Dart side, and Dart also needs to return different types of data +to JS. These data types include not only serializable strings, numbers, objects, and arrays, but also non-serializable +data types. These data are unique, cannot be duplicated, and must ensure that the value obtained after cross-language +transmission is still the original object, such as when the type of data being passed is an Element object. + +In addition to non-duplicable objects, the types of data can also be functions, used to directly expose Dart's functions +in JavaScript for developers to call using JavaScript. And these aren't just limited to synchronous calls; they also +need to support JavaScript functions returning a Promise, or passing an async-await function. + +This setup is particularly important in managing complex interactions in web applications where the frontend ( +JavaScript) and backend (Dart, in this case) need to maintain consistent states and perform various real-time +operations. This interplay must be seamless, especially when dealing with non-serializable data types, to ensure the +integrity and consistency of data throughout the application. The system could handle these unique objects appropriately +to maintain their identity and state across these interactions. Moreover, supporting various types of function calls, +including those that are asynchronous, enhances the responsiveness and user experience of the application by efficiently +handling tasks that may take some time to complete. + +Therefore, using JSON as the only medium for data transfer is insufficient to meet all these needs, so a new data +communication format is required. This format should not only transmit regular value types but also reference types and +even functions. + +Firstly, we need a more efficient data structure compared to JSON. This structure should not require additional parsing +for processing; it can be used directly. + +ui_command + +WebF utilizes the NativeValue C struct as its communication protocol, determining the data type with a uint32_t and +using the remaining 12 bytes to store data. This structure, compared to using JSON, saves time that would otherwise be +spent parsing strings, significantly enhancing communication efficiency. + +Communication between JavaScript and Dart occurs through C/C++ acting as a bridge. Data communication between JavaScript +and C/C++ can be achieved through the C API provided by QuickJS. However, direct object transfer between Dart and C++ +isn't possible because Dart's object transfer is reference-based, while C/C++ involves pointer passing. Therefore, +standard Dart objects cannot be directly transmitted through FFI, nor is it easy to compare values. + +ui_command + +To resolve the aforementioned issues, we require a shared data structure that can be accessed by both Dart and C++. +Then, both C++ objects and Dart objects should hold the pointer address of this data structure simultaneously. + +ui_command + +This method means that when there's a need to pass an object from C++ to the Dart environment, it's only necessary to +pass the pointer of the shared data structure into Dart. Then, the actual Dart object can be identified based on this +pointer address using an existing mapping table. Similarly, when a Dart object needs to be passed to C++, only the +address of the shared data structure needs to be transmitted. + +Subsequently, in C++, the pointer to the corresponding JavaScript object can be retrieved based on the pointer stored +within the shared data structure. + +This technique facilitates a smooth and efficient object transfer between the different environments, ensuring data +consistency and integrity while avoiding the performance overhead of serialization and deserialization. It leverages +direct memory access and pointer sharing, which is significantly faster and more resource-efficient, especially when +dealing with complex or high-volume data transitions. + +#### Managing the lifecycle of Element objects through JavaScript GC + +Managing the lifecycle of Element objects through JavaScript GC involves JavaScript calling Dart Element objects through +APIs implemented with C++ Binding. This process spans three languages, creating significant challenges in determining +the right time for memory recycling. + +When a JavaScript Element object is no longer in use and gets released by JavaScript GC, the Dart-side Element doesn't +recognize its unavailability, leading to persistent memory storage and a memory leak issue. + +Therefore, a notification mechanism is necessary. When an Element is released by JavaScript GC, Dart needs to be +informed to carry out the memory release on its side. + +QuickJS API offers a function that listens for the timing of objects being reclaimed by GC, allowing for a callback +function to be executed right before this object is released. + +With this callback function, WebF can seamlessly integrate the lifecycles of JavaScript and Dart objects. When a +JavaScript Element is released by GC, this callback can be used to unlink the reference to the Dart-side Element, +allowing Dart's GC to take over the destruction of this Element. + diff --git a/website/docs/resources/imgs/api_organized.png b/website/docs/resources/imgs/api_organized.png new file mode 100644 index 0000000000..b61b1f3810 Binary files /dev/null and b/website/docs/resources/imgs/api_organized.png differ diff --git a/website/docs/resources/imgs/architecture_overview.png b/website/docs/resources/imgs/architecture_overview.png new file mode 100644 index 0000000000..89b698d5bd Binary files /dev/null and b/website/docs/resources/imgs/architecture_overview.png differ diff --git a/website/docs/resources/imgs/binding_code.png b/website/docs/resources/imgs/binding_code.png new file mode 100644 index 0000000000..27b6e590e1 Binary files /dev/null and b/website/docs/resources/imgs/binding_code.png differ diff --git a/website/docs/resources/imgs/command_buffer.png b/website/docs/resources/imgs/command_buffer.png new file mode 100644 index 0000000000..14bf663a55 Binary files /dev/null and b/website/docs/resources/imgs/command_buffer.png differ diff --git a/website/docs/resources/imgs/dart_js_thread.png b/website/docs/resources/imgs/dart_js_thread.png new file mode 100644 index 0000000000..6651a2a3bb Binary files /dev/null and b/website/docs/resources/imgs/dart_js_thread.png differ diff --git a/website/docs/resources/imgs/gen_bindings.png b/website/docs/resources/imgs/gen_bindings.png new file mode 100644 index 0000000000..2f0423aa4e Binary files /dev/null and b/website/docs/resources/imgs/gen_bindings.png differ diff --git a/website/docs/resources/imgs/rendering_process.png b/website/docs/resources/imgs/rendering_process.png new file mode 100644 index 0000000000..ce1ebcda2a Binary files /dev/null and b/website/docs/resources/imgs/rendering_process.png differ diff --git a/website/docs/resources/imgs/single_thread.png b/website/docs/resources/imgs/single_thread.png new file mode 100644 index 0000000000..5b78107428 Binary files /dev/null and b/website/docs/resources/imgs/single_thread.png differ diff --git a/website/docs/tutorials/getting-started/_category_.json b/website/docs/tutorials/getting-started/_category_.json new file mode 100644 index 0000000000..6b0c47e7b6 --- /dev/null +++ b/website/docs/tutorials/getting-started/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 1, + "label": "Getting Started", + "collapsible": true, + "collapsed": false +} \ No newline at end of file diff --git a/website/docs/tutorials/getting-started/introduction.md b/website/docs/tutorials/getting-started/introduction.md new file mode 100644 index 0000000000..5e3cb7e612 --- /dev/null +++ b/website/docs/tutorials/getting-started/introduction.md @@ -0,0 +1,55 @@ +--- +sidebar_position: 1 +title: Introduction +--- + +# What is WebF? + +WebF is a Flutter package that enables developers to build their Flutter apps using HTML/CSS and JavaScript in one code +base and deploy to mobile and desktop platforms. + +It offers a subset of browser capabilities, including HTML, CSS, and a JavaScript runtime environment with built-in DOM, +Window, Document, and other APIs defined in W3C/WhatWG standards. + +This allows developers to utilize popular web frameworks, libraries, and other utilities to build apps compatible with +both WebF and web browsers. + +By embedding an [optimized QuickJS engine](https://github.com/openwebf/quickjs), WebF can reduce loading time by 50% +compared to WebView. + +All Flutter capabilities and its ecosystem are fully accessible to web developers. +This makes it possible for them to embed a native performance video player or a 3D game engine into the web without +experiencing the performance loss associated with WebAssembly or WebGL in WebView. + +## Getting Started + +We recommend you to start with the [tutorial](/docs/tutorials/getting-started/quick-start), which guides you through the +process of developing an WebF app and distributing it to users. + +The [examples](https://github.com/openwebf) and [API documentation](./) are also good places to browse around and +discover new things. + +## What is in the docs? + +There are two major kinds of developers who are expected to read this documentation -- Web developers and Flutter/client +developers. + +These docs are consists of the following different parts: + +1. Guide for Web Developers: An end-to-end guide on how to create your first WebF app using HTML/CSS and JavaScript. +2. Guide for Flutter/Client Developers: An end-to-end guide on how to customize behavior and extend WebF's capabilities + using Flutter. +3. Performance & Optimizations: Crucial methods for measuring and improving the performance of WebF. +4. Best Practices: Essential checklists to keep in mind when developing a WebF app. +5. Resources: Design documents and an overview of the architecture. +6. Contributing Guide: Instructions for developers who want to contribute to WebF. + +## Getting help + +Are you getting stuck anywhere? Here are a few links to places to look: + +1. If you need help developing your app, [our community Discord server](https://discord.gg/jkUsNGndFP) is a great + place to receive advice from other WebF app developers. +2. If you suspect you're encountering a bug with the WebF, please check the GitHub issue tracker to see if any existing + issues that match your problem. If not, feel free to fill out our bug report template and submit a new issue. +3. If you want to become a contributor of WebF, please contact [andycall](https://discordapp.com/users/375903419610824707) via discord directly. \ No newline at end of file diff --git a/website/docs/tutorials/getting-started/quick-start.md b/website/docs/tutorials/getting-started/quick-start.md new file mode 100644 index 0000000000..3183d47fd9 --- /dev/null +++ b/website/docs/tutorials/getting-started/quick-start.md @@ -0,0 +1,217 @@ +# Quick Start + +This guide will walk you through the process of creating a HelloWorld App with Vue.js and running it in WebF. + +By the end of this tutorial, your app will be functioning on both desktop and mobile platforms with the same behavior. + +:::caution + +Since Flutter for Web is not compatible with WebF, ensure that you set your running platform to either mobile or desktop systems, rather than Chrome. + +::: + +## Prerequisites + +To use WebF, you need a Flutter environment. Each version of Flutter has its own range of compatible WebF versions, +Ensure that you select the correct Flutter version that matches both WebF and Flutter. + +| WebF | Flutter | +|--------------------|-----------------| +| >= 0.12.0 < 0.14.0 | 3.0.x | +| >= 0.14.0 < 0.15.0 | 3.3.x and 3.7.x | +| >= 0.15.0 < 0.16.0 | 3.10.x | +| >= 0.16.0 < 0.17.0 | 3.13.x | + +:::tip + +For more info how to install the Flutter environment, please refer to https://docs.flutter.dev/get-started/install. + +::: + +In this tutorial, we will use webf `0.15.1` and flutter `3.10.0` as an example. + +:::info + +If you are a Web developer, you may encounter problems trying to install the Flutter environment. +WebF offers a prebuilt desktop app allow you to quickly examine the HTML/CSS and JavaScript abilities without needing +to install any Flutter developer environments. + +Read more at https://www.npmjs.com/package/@openwebf/cli + +::: + +## Install WebF + +Add the following code to your package's pubspec.yaml file and run `flutter pub get`. + +```yaml +dependencies: + webf: ^0.15.1 +``` + +Now in your Dart code: + +```dart +import 'package:webf/webf.dart'; +import 'package:webf/devtools.dart'; +``` + +And initialize the WebFWebSocket plugin before initialize flutter framework. + +```dart +void main() { + runApp(MyApp()); +} +``` + +## Set up a Web app develop environment + +The runtime capabilities for Web apps provided by WebF follow by WhatWG/W3C standards, which are the same +standards for Web browsers. Once the necessary required browser features are supported by WebF, the framework or library +originally designed +for Web browsers can be run in WebF. + +In this example, We will set up a Vue app let it running in WebF. + +To create a Vue app, you need to install [Node.js](https://nodejs.org/en). We recommend that you use the latest LTS +version available. + +```bash +npm install -g @vue/cli +``` + +:::info +If you are a Web developers, you might be curious why we use vue-cli instead of [Vite](https://vitejs.dev/) (Another +buildtools +released by the Vue.js team) to create the App. +The app created by Vite requires ESM module support, which is not currently supported by WebF. However, we plan to +support +this in the future versions of WebF. +::: + +:::info Can I use React instead of Vue? + +Absolutely, both React.js and Vue.js have been thoroughly tested and can run in WebF without any configuration. You can +use create-react-app to create a React.js app and run it in WebF. + +::: + +Run the following command to create and start a vue web app: + +```bash +vue create app +cd app +npm run serve +``` + +Once the Vue development server has started, you can open your web apps in a browser at `http://:8080/`. + +## Add WebF to your Flutter app + +:::tip +If you're unsure how to create and run a Flutter app, you can find more information at +Flutter's [Getting Started Guide](https://docs.flutter.dev/get-started/test-drive). +::: + +The WebF widget is a stateful Flutter Widget that allows you to embed web content rendered by WebF into your Flutter +apps. Add it to your flutter app to enable build your UI with HTML/CSS and JavaScript. + +```dart +@override +Widget build(BuildContext context) { + final MediaQueryData queryData = MediaQuery.of(context); + final Size viewportSize = queryData.size; + + return Scaffold( + body: Center( + child: Column( + children: [ + WebF( + devToolsService: ChromeDevToolsService(), // Enable Chrome DevTools Services + viewportWidth: viewportSize.width - queryData.padding.horizontal, // Adjust the viewportWidth + viewportHeight: viewportSize.height - queryData.padding.vertical, // Adjust the viewportHeight + bundle: WebFBundle.fromUrl('http://:8080/'), // The page entry point + ), + ], + ), + )); +} +``` + +:::tip +There are multiple ways to load a web app: from the network, assets, disk, or even a sequence of strings. For more info, +please refer +to [loading-web-contents-from-disk](/docs/tutorials/guides-for-flutter-developer/loading-web-contents-from-disk). +::: + +## Build and run your Flutter app + +Now it's time to build and try. + +:::tip +If you're unsure how to create and run a Flutter app, you can find more information at +Flutter's [Getting Started Guide](https://docs.flutter.dev/get-started/test-drive). +::: + +After the app build completes, you’ll see your vue web app is running on your device. + +![img](/img/helloworld.png) + +## Use Hot-Restart instead Hot-Reload + +Flutter offers a fast development cycle with Hot Reload and Hot-Restart, the ability to reload the code of a live +running app without restarting or losing app state. + +Unfortunately, you cannot use the Hot Reload feature when you make any changes to your web app. + +Instead, Hot Restart is available to reload Web contents rendered by WebF. + +

+Click the hot-restart icon to see changes in your simulator, emulator or device when you make any modifications to your Web app. +

+ +## Measure performance + +:::caution +Avoid testing your app's performance in debug mode. +::: + +Up until now, you’ve been running your app in debug mode. Debug mode in Flutter trades performance for useful developer +features and can be 3x-4x slower than Profile or Release builds. + +Once you are ready to analyze performance or release your app, +consult [Flutter's build modes](https://docs.flutter.dev/testing/build-modes) for more details. + +## Integration and Deployment + +The integration and deployment of WebF are no different from standard Flutter apps. + +Refer to the documentation at https://docs.flutter.dev/reference/supported-platforms for more details. + +:::note +Not all platforms supported by Flutter are supported by WebF. + +Here are the platforms supported by WebF: + +1. iOS +2. Android +3. macOS +4. Linux +5. Windows + +The following platform is currently not supported, but will be added in the future: + +1. Web + +::: + +## What's Next + +Now that you have an app built with Vue.js and running on both mobile and desktop platforms with Flutter, +you might be wondering about the next steps. + ++ If you're a Web developer, you might be curious about the extent of Web features that can be used in WebF. Learn more + by visiting the [Guides for Web Developer](/docs/tutorials/guides-for-web-developer/overview). + ++ If you're a Flutter developers, visit the [Guides for Flutter developer](/docs/tutorials/guides-for-flutter-developer/overview) + to learn how to customize and extend WebF with Flutter. diff --git a/website/docs/tutorials/guides-for-flutter-developer/_category_.json b/website/docs/tutorials/guides-for-flutter-developer/_category_.json new file mode 100644 index 0000000000..fab25092c9 --- /dev/null +++ b/website/docs/tutorials/guides-for-flutter-developer/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 3, + "label": "Guides For Flutter/Mobile Dev", + "collapsible": true, + "collapsed": false +} \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-flutter-developer/adding-flutter-widgets-to-html.md b/website/docs/tutorials/guides-for-flutter-developer/adding-flutter-widgets-to-html.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/website/docs/tutorials/guides-for-flutter-developer/control_pages_in_webf.md b/website/docs/tutorials/guides-for-flutter-developer/control_pages_in_webf.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/website/docs/tutorials/guides-for-flutter-developer/imgs/architecture.png b/website/docs/tutorials/guides-for-flutter-developer/imgs/architecture.png new file mode 100644 index 0000000000..0da097b7dd Binary files /dev/null and b/website/docs/tutorials/guides-for-flutter-developer/imgs/architecture.png differ diff --git a/website/docs/tutorials/guides-for-flutter-developer/loading-web-contents-from-disk.md b/website/docs/tutorials/guides-for-flutter-developer/loading-web-contents-from-disk.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/website/docs/tutorials/guides-for-flutter-developer/overview.md b/website/docs/tutorials/guides-for-flutter-developer/overview.md new file mode 100644 index 0000000000..a90e7cfa40 --- /dev/null +++ b/website/docs/tutorials/guides-for-flutter-developer/overview.md @@ -0,0 +1,69 @@ +--- +sidebar_position: 1 +title: Overview +--- + +This guide was designed for developers who have experiences of Flutter development. + +WebF offers enhanced customization and optimization for web applications. It ensures that your application runs +seamlessly, behaving more like native Flutter apps. + +## How to Use this guides + +This guides will provide a brief introduction to WebF, and it's divided into topics to teach you how to customize the +optimize WebF apps. + +If you desire features that may not be provided by WebF, please submit an issue to us. + +## How WebF works in Flutter + +WebF is a rendering engine built on the foundation of Flutter's rendering framework. + +It extends the Flutter RenderObject class to achieve the layout and painting capabilities required by CSS Style and +implements the DOM tree and various CSS selectors. + +Through Dart's FFI, WebF integrates QuickJS to execute JavaScript. With comprehensive support for Web APIs, it allows +you to drive web frameworks and applications directly without the need for any polyfills or adaptors. + +WebF also incorporates a debugging service that is compatible with the Chrome DevTools Protocol. + +This allows web developers to connect to WebF through Chrome DevTools and use Chrome DevTools to debug WebF pages just +like regular web pages. + +There is an architecture overview. + +![img](./imgs/architecture.png) + +## The relationship between WebF and Flutter + +WebF offers Flutter developers a single WebF widget to render web content alongside Flutter apps. + +Integrating WebF into Flutter apps is as straightforward as using other widgets, and you can place WebF anywhere within +your Flutter application. + +Using multiple WebF instances within the same Flutter app is also supported. Each WebF widget has its own rendering +context and JSContext, similar to separate pages in web browsers. + +## When and how to use WebF in your Flutter apps + +When to use WebF: + +1. You want certain parts of your app to be dynamically updated (without reinstalling the app). +2. You want to deploy your application across various platforms, including mobile, desktop, and mini-app (specific to + mainland China). +3. Your team comprises numerous developers who are proficient in web development but not in Flutter or Native. +4. You are seeking a WebView replacement to running your web app inside your app for performance reasons. + +How to use WebF: + +1. WebF was designed for developer who have experienced with web development, make sure you and your team are familiar + with web development before using WebF. +2. WebF was meticulously designed to be compatible with web browsers, striving to maintain compatibility with the + existing web development ecosystem. While the features and tools for web development encompass a vast collection with + hundreds of APIs, supporting these libraries remains a significant task, and we still have more work ahead. So be + patience and let us known and keeping up the date with WebF if you want your favorite web libraries to be working in + WebF. +3. The primary advantage of WebF over WebView lies in its capability to integrate any Flutter widget within WebF apps. + This feature allows you to tap into the expansive Flutter development ecosystem, combining the best of both Flutter + and the Web. To make the most of this, try using the `WidgetElement` to encapsulate your preferred Flutter widgets and + incorporate them into your WebF web applications diff --git a/website/docs/tutorials/guides-for-web-developer/SSR_support.md b/website/docs/tutorials/guides-for-web-developer/SSR_support.md new file mode 100644 index 0000000000..d1e4a090b8 --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/SSR_support.md @@ -0,0 +1,14 @@ +--- +sidebar_position: 5 +title: SSR Support +sidebar_class_name: hidden +--- + +Server-Side Rendering (SSR) is a technique in which a web server renders a full web page on the server before sending it +to the browser. + +This is in contrast to Client-Side Rendering (CSR), where the browser receives a minimal HTML page and then uses +JavaScript to fetch data and generate the final content. + +Since WebF have built-in support for HTML, DOM API and selectors, it had been satisfied for all the needs to running the +SSR using frameworks like Next.js (for React), Nuxt.js (for Vue). \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/_category_.json b/website/docs/tutorials/guides-for-web-developer/_category_.json new file mode 100644 index 0000000000..b9444b361f --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 2, + "label": "Guides For Web Dev", + "collapsible": true, + "collapsed": false +} \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/canvas_support.md b/website/docs/tutorials/guides-for-web-developer/canvas_support.md new file mode 100644 index 0000000000..a36307a732 --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/canvas_support.md @@ -0,0 +1,107 @@ +--- +sidebar_position: 6 +title: Canvas Support +--- + +# Canvas Support + +The Canvas 2D API is a feature in webf/browser that enables drawing and manipulating graphics directly in an HTML canvas +element using JavaScript. + +This provides a way to render graphics, animations, and even games without relying on plugins or external tools. + +## Canvas Element + +The starting point is the `` HTML element, which creates a blank canvas that you can draw upon: + +```html + + +``` + +This creates a canvas of 400 pixels in width and 200 pixels in height. + +However, displaying the canvas element by itself will not show anything besides a blank rectangle (or sometimes nothing at all, unless given a border or background). + +## Drawing on the Canvas + +To draw on the canvas, you use JavaScript and the Canvas API. The key object here is the 2D rendering context, which you can obtain from any canvas element. + +```javascript +let canvas = document.getElementById('myCanvas'); +let ctx = canvas.getContext('2d'); +``` + +### Drawing Commands + +### Paths: + +- **beginPath()**: Resets the current path. +- **closePath()**: Connects the last point in the path to the starting point. +- **moveTo(x, y)**: Moves the pen to the specified coordinates without drawing. +- **lineTo(x, y)**: Draws a line from the current position to the specified coordinates. +- **arc(x, y, radius, startAngle, endAngle, antiClockwise)**: Draws an arc or a section of a circle. If the `antiClockwise` argument is `true`, the arc is drawn counterclockwise; otherwise, it's drawn clockwise. +- **arcTo(x1, y1, x2, y2, radius)**: Draws an arc using control points and a radius. +- **quadraticCurveTo(cp1x, cp1y, x, y)**: Draws a quadratic Bézier curve. +- **bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)**: Draws a cubic Bézier curve. + +### Drawing Styles: + +- **fillStyle**: Property to set the color, gradient, or pattern to fill shapes. +- **strokeStyle**: Property to set the color, gradient, or pattern for shape outlines. +- **createLinearGradient(x1, y1, x2, y2)**: Creates a linear gradient object. +- **createRadialGradient(x1, y1, r1, x2, y2, r2)**: Creates a radial (or circular) gradient object. +- **createPattern(image, type)**: Creates a pattern using a specified image (or another canvas) and repetition type (`"repeat"`, `"repeat-x"`, `"repeat-y"`, or `"no-repeat"`). + - CanvasPattern.setTransform currently not supported. + +### Drawing Shapes: + +- **fill()**: Fills the current path. +- **stroke()**: Outlines the current path. +- **clearRect(x, y, width, height)**: Clears the specified rectangular area, making it transparent. +- **fillRect(x, y, width, height)**: Draws a filled rectangle. +- **strokeRect(x, y, width, height)**: Draws a rectangular outline. + +### Text: + +- **font**: Property to set the current font properties. +- **textAlign**: Property to set the text alignment (`"start"`, `"end"`, `"left"`, `"right"`, or `"center"`). +- **textBaseline**: Property to set the baseline alignment (`"top"`, `"hanging"`, `"middle"`, `"alphabetic"`, `"ideographic"`, or `"bottom"`). +- **fillText(text, x, y, [maxWidth])**: Fills a text string at the specified coordinates. +- **strokeText(text, x, y, [maxWidth])**: Outlines a text string at the specified coordinates. +- ~~**measureText(text)**: Returns a `TextMetrics` object containing information about the width of the text.~~ + +### Image Drawing: + +- **drawImage(image, dx, dy, [dWidth, dHeight])**: Draws an image, video frame, or another canvas onto the canvas. This method has multiple overloads to support cropping and scaling. + +### Global Composite Operations: + +- ~~**globalAlpha**: Property to set the global transparency level.~~ +- ~~**globalCompositeOperation**: Property to set how shapes and images are drawn onto the existing content. Common values include `"source-over"`, `"destination-over"`, `"multiply"`, `"screen"`, etc.~~ + +### Line Styles: + +- **lineCap**: Property to set the end style of lines (`"butt"`, `"round"`, or `"square"`). +- **lineJoin**: Property to set the corner style of paths (`"bevel"`, `"round"`, or `"miter"`). +- **lineWidth**: Property to set the width of lines. +- ~~**setLineDash(segments)**: Sets the current line dash pattern.~~ +- ~~**getLineDash()**: Returns the current line dash pattern.~~ +- **lineDashOffset**: Property to set the offset for the line dash pattern. + +### Transformations: + +- **scale(x, y)**: Scales the canvas units. +- **rotate(angle)**: Rotates the canvas around the current origin. +- **translate(x, y)**: Moves the canvas origin to a different point. +- **transform(a, b, c, d, e, f)**: Multiplies the current transformation matrix with the given matrix. +- **setTransform(a, b, c, d, e, f)**: Resets the current transform to the identity and then invokes `transform()`. +- **resetTransform()**: Resets the current transform to the identity matrix. + +### Other Commands: + +- **clip()**: Clips the region using the current path. +- **save()**: Saves the current drawing state to a stack. +- **restore()**: Restores the drawing state from the stack. +- ~~**isPointInPath(x, y)**: Checks if the given point is inside the current path.~~ +- ~~**isPointInStroke(x, y)**: Checks if the given point is on the path's stroke.~~ \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/background_and_borders.md b/website/docs/tutorials/guides-for-web-developer/css_support/background_and_borders.md new file mode 100644 index 0000000000..6ce49604fd --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/background_and_borders.md @@ -0,0 +1,135 @@ +--- +sidebar_position: 10 +title: Background and Borders +--- + +Both background and borders play a crucial role in styling and visually differentiating elements on a web page. + +## Background + +The background property in CSS is used to set the background effects for an element. + +It's a shorthand property, meaning it can be used to set several background properties at once. + +### Properties: + +**background-color**: Sets the background color of an element. +```css +div { + background-color: red; +} + ``` + +**background-image**: Sets one or more background images for an element. +```css +div { + background-image: url('path/to/image.jpg'); +} + ``` + +**background-repeat**: Sets if/how a background image will be repeated. +```css +div { + background-repeat: no-repeat; /* Other values: repeat, repeat-x, repeat-y */ +} + ``` + +**background-position**: Sets the starting position of a background image. +```css +div { + background-position: center center; /* Can use values like top, bottom, left, right, or percentages */ +} + ``` + +**background-size**: Specifies the size of the background images. +```css +div { + background-size: cover; /* Other values: contain, 50% 50%, auto */ +} +``` + +**background-attachment**: Determines whether the background image scrolls with the content or remains fixed. +```css +div { + background-attachment: fixed; /* Other value: scroll */ +} +``` + +**background-clip**: Determines the painting area of the background. +```css +div { + background-clip: border-box; /* Other values: padding-box, content-box */ +} +``` + +**background-origin**: Determines the positioning area of the background images. +```css +div { + background-origin: padding-box; /* Other values: border-box, content-box */ +} +``` + +### Shorthand: + +You can combine multiple background properties into one using the shorthand: +```css +div { + background: red url('path/to/image.jpg') no-repeat center center / cover; +} +``` + +## Borders + +The `border` property is used to set the borders around an element. + +### Properties: + +**border-width**: Sets the width of the borders. +```css +div { + border-width: 2px; +} +``` + +**border-style**: Sets the style of the borders (e.g., solid). + +```css +div { + border-style: solid; +} +``` + +**border-color**: Sets the color of the borders. +```css +div { + border-color: blue; +} +``` + +**border-radius**: Used to round the corners of an element. +```css +div { + border-radius: 10px; +} +``` + +### Individual Sides: + +You can also target individual sides of an element: +```css +div { + border-top: 2px solid blue; + border-right: 3px dashed red; + border-bottom: 4px dotted green; + border-left: 5px double purple; +} +``` + +### Shorthand: + +The shorthand for setting borders is: +```css +div { + border: 2px solid blue; +} +``` \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/box_shadow_filter.md b/website/docs/tutorials/guides-for-web-developer/css_support/box_shadow_filter.md new file mode 100644 index 0000000000..90164ed4b4 --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/box_shadow_filter.md @@ -0,0 +1,71 @@ +--- +sidebar_position: 8 +title: Box Shadow and Filters +--- + +Both box-shadow and filter are CSS properties that allow you to enhance the visual appearance of elements. + +Let's dive into each of them: + +## Box Shadow + +The box-shadow property is used to add shadow effects around an element's frame. + +You can set multiple effects separated by commas. + +A box shadow is described by X and Y offsets relative to the element, blur and spread radii, and a color. + +Syntax: +```css +box-shadow: [horizontal offset] [vertical offset] [blur radius] [optional spread radius] [color]; +``` + +Examples: + +- **Simple Shadow**: + ```css + box-shadow: 5px 5px 5px #888888; + ``` + +- **Shadow with Spread**: + ```css + box-shadow: 5px 5px 5px 10px #888888; + ``` + +- **Inset Shadow** (shadow inside the element): + ```css + box-shadow: inset 5px 5px 5px #888888; + ``` + +- **Multiple Shadows**: + ```css + box-shadow: 3px 3px 5px #666, -3px -3px 5px #ccc; + ``` + +## Filters: + +The `filter` property provides visual effects like blurring or color shifting an element. Filters are commonly used to adjust the rendering of images, backgrounds, and borders. + +Here are some of the functions you can use with the `filter` property: + +- **`blur()`**: Applies a Gaussian blur to the element. + ```css + filter: blur(5px); + ``` + +- **`grayscale()`**: Converts the element to grayscale. + ```css + filter: grayscale(100%); /* Full grayscale */ + ``` + +- **`sepia()`**: Converts the element to sepia. + ```css + filter: sepia(100%); /* Full sepia */ + ``` + +You can also chain multiple filter functions together: +```css +filter: grayscale(50%) blur(5px); +``` + + diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/cascade_inheritance.md b/website/docs/tutorials/guides-for-web-developer/css_support/cascade_inheritance.md new file mode 100644 index 0000000000..652540be64 --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/cascade_inheritance.md @@ -0,0 +1,85 @@ +--- +sidebar_position: 4 +title: Cascade and Inheritance +--- + +WebF supports cascade and inheritance in CSS. + +## Cascade support in CSS + +The cascade is a fundamental concept in CSS that defines how webf/browser should determine the final value for a CSS +property on an element when there might be multiple conflicting rules. + +The cascade determines the priority of different +styles based on their specificity, and order of declaration. + +1. Specificity: This determines which CSS rule is applied by the browser based on which rule is more specific or + targeted to an element. + Inline styles (e.g., style="color: red;" on an element) have the highest specificity. + ID selectors have higher specificity than class, attribute, and pseudo-class selectors. + Class, attribute, and pseudo-class selectors have higher specificity than type selectors (e.g., h1). + Universal selectors (*), combinators (+, >, ~, ' ') and the negation pseudo-class (:not()) have no specificity. +2. Order of declaration: If multiple rules have equal specificity, the last rule declared wins. +3. Importance: The !important annotation on a style can override styles based on the factors mentioned above. However, + it's worth noting that over-reliance on !important is generally discouraged as it can make stylesheets difficult to + understand and maintain. + +An example to illustrate: + +```css +/* This has lower specificity */ +div { + color: blue; +} + +/* This has higher specificity because it targets an ID */ +#myDiv { + color: red; +} + +/* This comes later and would override previous styles with equal specificity */ +div { + color: green; +} +``` + +In the above, an element with the ID "myDiv" would be colored red, despite the later rule, because ID selectors have +higher specificity. + +## Inheritance in CSS + +Inheritance is a key concept in CSS that pertains to the way certain properties are passed from parent elements to their +descendants (children, grandchildren, etc.). + +When you set a style on an element, some properties of that style will automatically be applied to its descendant +elements unless specified otherwise. This behavior helps reduce redundancy. + +For example, if you set the color property on a parent element, its child elements will inherit that color by default: + +```css +/* CSS */ +div { + color: red; +} + +``` + +```html + +
+ This text is red. +

This paragraph text is also red because it inherits the color from the parent div.

+
+``` + +The following list contains all the CSS properties for which WebF currently supports inheritance: + +1. `color` +2. `font-family` +3. `font-size` +4. `font-style` +5. `font-weight` +6. `font` +7. `line-height` +8. `text-align` +9. `visibility` diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/flex_layout.md b/website/docs/tutorials/guides-for-web-developer/css_support/flex_layout.md new file mode 100644 index 0000000000..55be0f8d79 --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/flex_layout.md @@ -0,0 +1,89 @@ +--- +sidebar_position: 9 +title: Flex Layout +--- + +The Flexbox (or flexible box) layout model in CSS is a way to design complex layout structures with a more predictable +way than traditional models, especially when it comes to distributing space and aligning items in complex layouts and +when the sizes of your items are unknown or dynamic. + +Learn how to use flex layout in CSS: https://css-tricks.com/snippets/css/a-guide-to-flexbox/ + +## Basics of Flexbox + +To use Flexbox, you need a container set to display: flex or display: inline-flex (if you want the container to behave +like an inline element). + +```css +.container { + display: flex; +} +``` + +### Main Components + ++ Flex Container: The parent element in which you apply display: flex or display: inline-flex. ++ Flex Items: The children of the flex container. + +### Main Axis and Cross Axis + ++ Main Axis: The primary axis along which flex items are laid out. It can be horizontal or vertical, depending on the + flex-direction property. ++ Cross Axis: The axis perpendicular to the main axis. + +### Properties for the Flex Container + ++ flex-direction: Defines the direction of the main axis. + + row (default): left to right + + row-reverse: right to left + + column: top to bottom + + column-reverse: bottom to top ++ flex-wrap: By default, flex items will try to fit onto one line. You can change that with this property. + + nowrap (default): all flex items on one line + + wrap: flex items wrap onto multiple lines + + wrap-reverse: flex items wrap onto multiple lines in reverse order ++ flex-flow: A shorthand for flex-direction and flex-wrap. ++ justify-content: Aligns flex items along the main axis. + + flex-start (default): items at the start of the container + + flex-end: items at the end of the container + + center: items at the center + + space-between: equal space between items + + space-around: equal space around each item + + space-evenly: equal space between and around each item ++ align-items: Aligns flex items along the cross axis. + + flex-start: items at the start of the container + + flex-end: items at the end of the container + + center: items at the center + + baseline: items aligned such as their baselines align + + stretch (default): stretch to fill the container (still respects min-width/max-width) ++ align-content: Aligns flex lines when there's extra space in the cross-axis. + + flex-start + + flex-end + + center + + space-between + + space-around + + stretch (default) + +### Properties for the Flex Items + ++ flex-grow: Defines the ability for a flex item to grow. Takes a unitless value that serves as a proportion. ++ flex-shrink: Defines the ability for a flex item to shrink. Takes a unitless value that serves as a proportion. ++ flex-basis: Defines the default size of an element before the remaining space is distributed. ++ flex: A shorthand for flex-grow, flex-shrink, and flex-basis. ++ align-self: Allows the default alignment (or the one specified by align-items) to be overridden for individual flex + items. + +### Example + +```css +.container { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; +} + +.item { + flex: 1; /* shorthand for flex-grow: 1, flex-shrink: 1, flex-basis: 0% */ +} +``` \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/flow_layout.md b/website/docs/tutorials/guides-for-web-developer/css_support/flow_layout.md new file mode 100644 index 0000000000..e44ef75c21 --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/flow_layout.md @@ -0,0 +1,48 @@ +--- +sidebar_position: 8 +title: Flow Layout +--- + +The flow layout, often referred to as "normal flow" in CSS, is the default layout mechanism by which webf/browser render +web page content. + +When elements are laid out according to the normal flow, they behave predictably based on their display value (block, +inline, etc.) and their source order in the HTML document. + +## Display Values: + +In the context of the flow layout, the two primary `display` values to consider are `block` and `inline`. + +- **Block-Level Elements**: + - These elements create a new "block" or "box" in the layout. + - They typically stretch the full width of their parent container and stack vertically. + - Examples: `div`, `h1`-`h6`, `p`, `ul`, `li`, etc. + +- **Inline-Level Elements**: + - These elements flow horizontally within their containing element, wrapping to the next line when they run out of space. + - They only take up as much width as necessary. + - Examples: `span`, `a`, `strong`, `em`, etc. + +## Flow Layout Behavior: + +- **Block-Level Elements**: + - Start on a new line and extend the full width of their parent container by default. + - Respect top and bottom margins, but adjacent vertical margins will collapse into a single margin of the size of the largest margin (known as "margin collapsing"). + - Respect padding and borders. + +- **Inline-Level Elements**: + - Flow within the content, from left to right in languages that are read this way. + - Do not start on a new line. + - Horizontal margins, padding, and borders are respected, but vertical ones might not affect layout significantly. + - Width and height properties do not apply. Instead, the content determines their size. + - They can't have block-level elements inside them. + +## Out of Flow: + +Elements can be taken out of the normal flow using properties like `position` (with values other than `static`). Once an element is out of the flow, it no longer affects the positioning of other elements in the normal flow. + +- **Positioned Elements**: Elements with `position` values of `relative`, `absolute`, `fixed`, or `sticky` are considered "positioned" and can be taken out of the normal flow, depending on the value. + +## Containing Blocks: + +In the flow layout, the containing block of an element is determined by the nearest block-level ancestor. This containing block defines the area in which the element is laid out. \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/imgs/box_model.png b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/box_model.png new file mode 100644 index 0000000000..9fd79f595a Binary files /dev/null and b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/box_model.png differ diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/imgs/class_list_style.png b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/class_list_style.png new file mode 100644 index 0000000000..620dc75b50 Binary files /dev/null and b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/class_list_style.png differ diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/imgs/class_name_style.png b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/class_name_style.png new file mode 100644 index 0000000000..3986473cce Binary files /dev/null and b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/class_name_style.png differ diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/imgs/computed_style.png b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/computed_style.png new file mode 100644 index 0000000000..b87466f90b Binary files /dev/null and b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/computed_style.png differ diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/imgs/inline_style.png b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/inline_style.png new file mode 100644 index 0000000000..1b7229a154 Binary files /dev/null and b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/inline_style.png differ diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/imgs/js_inline_style.png b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/js_inline_style.png new file mode 100644 index 0000000000..12c593960b Binary files /dev/null and b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/js_inline_style.png differ diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/imgs/link_stylesheet.png b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/link_stylesheet.png new file mode 100644 index 0000000000..4cac8dce93 Binary files /dev/null and b/website/docs/tutorials/guides-for-web-developer/css_support/imgs/link_stylesheet.png differ diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/index.md b/website/docs/tutorials/guides-for-web-developer/css_support/index.md new file mode 100644 index 0000000000..edb9d700ec --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/index.md @@ -0,0 +1,41 @@ +--- +sidebar_position: 4 +title: CSS Support +--- + +WebF implements it owner layout system based on Flutter's rendering systems and provides you the essential CSS abilities +to build your apps with your existing CSS acknowledges. + +:::note +The CSS support in WebF is still under heavy development. It requires more developer and times to getting involved to +become compatible with popular CSS UI libraries like `tailwindcss` or others. +If you encounter layout issues when using UI libraries, try to report the issue to us and implement your layout without +using the UI libraries. +::: + +To gain a clear understanding of which CSS properties and methods can be used in WebF. We can divide the CSS into the follow +categories: + +1. [Using CSS in HTML and JavaScript](/docs/tutorials/guides-for-web-developer/css_support/use_css) +2. [CSS Selectors](/docs/tutorials/guides-for-web-developer/css_support/selectors) +3. [CSS cascade and inheritance](/docs/tutorials/guides-for-web-developer/css_support/cascade_inheritance) +4. [Styling Text and Fonts](/docs/tutorials/guides-for-web-developer/css_support/styling_text_and_font) +5. [The Box Model](/docs/tutorials/guides-for-web-developer/css_support/the_box_model) +6. [Overflow and scrolling](/docs/tutorials/guides-for-web-developer/css_support/overflow_scrolling) +7. [Value and Units](/docs/tutorials/guides-for-web-developer/css_support/value_and_units) +8. [Sizing Items](/docs/tutorials/guides-for-web-developer/css_support/sizing_items) +9. [Box Shadow and Filters](/docs/tutorials/guides-for-web-developer/css_support/box_shadow_filter) +10. [Box Shadow and Filters](/docs/tutorials/guides-for-web-developer/css_support/transition_and_animations) +11. [Flow Layout](/docs/tutorials/guides-for-web-developer/css_support/flow_layout) +12. [Flex layout](/docs/tutorials/guides-for-web-developer/css_support/flex_layout) +13. [Background and Borders](/docs/tutorials/guides-for-web-developer/css_support/background_and_borders) +14. [Positioning](/docs/tutorials/guides-for-web-developer/css_support/positioning) + +## Unsupported CSS features currently + +1. [CSS Cascade layers](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers) +2. [Floats layout](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Floats) +3. [Table](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Styling_tables) +4. [Grid Layout](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Grids) +5. [Setting Text directions](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Handling_different_text_directions) +6. [Multiple Column layout](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Multiple-column_Layout) \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/overflow_scrolling.md b/website/docs/tutorials/guides-for-web-developer/css_support/overflow_scrolling.md new file mode 100644 index 0000000000..a6fd7ba9c1 --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/overflow_scrolling.md @@ -0,0 +1,56 @@ +--- +sidebar_position: 5 +title: Overflow and Scrolling +--- + +## Overflowing content + +The `overflow` property in CSS is used to control what happens when content overflows its box. + +This can be especially relevant for elements that have a fixed width and height. The overflow can be caused by content ( +like text or images) that's too large, or by content that's dynamically added to an element, such as with JavaScript. + +The overflow property has several values: + +**visible (default)**: Content is not clipped, and it renders outside the element's box. + +```css +div { + overflow: visible; +} +``` + +**hidden**: Content is clipped, and any content that overflows the element's box will be hidden. + +```css +div { + overflow: hidden; +} +``` + +**scroll**: Content is clipped, but a scrollbar is always added to the element, even if the content does not overflow. + +```css +div { + overflow: scroll; +} +``` + +**auto**: Content is clipped, and a scrollbar is added only if the content overflows the element's box. + +```css +div { + overflow: auto; +} +``` + +### Separate Overflow for Horizontal and Vertical: + +You can also control the overflow behavior separately for the horizontal and vertical axes using overflow-x and overflow-y: + +```css +div { + overflow-x: auto; /* Horizontal overflow */ + overflow-y: hidden; /* Vertical overflow */ +} +``` \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/positioning.md b/website/docs/tutorials/guides-for-web-developer/css_support/positioning.md new file mode 100644 index 0000000000..d108251f1f --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/positioning.md @@ -0,0 +1,203 @@ +--- +sidebar_position: 12 +title: Positioning +--- + +The Positioned Layout in CSS refers to the behavior of elements whose position property is set to a value other than +static (which is the default value). + +Positioned elements can be laid out based on their containing elements or other +reference points, and they do not follow the standard flow of the document, hence they are "out of flow." + +## Relative positioned layout + +When a box's position property set to relative. + +This type of positioning allows you to move an element from its normal +position in the flow of the document using the top, right, bottom, and left offset properties. + +Using these offset properties will move the element from where it would normally be in the document flow. + +For example: + +```css +.relative-box { + position: relative; + top: 10px; + left: 20px; +} +``` + +This will move the .relative-box element 10 pixels down and 20 pixels to the right from its original position. + +**Space Reservation:** + +An essential characteristic of position: relative is that the element still occupies its original space in the layout. +So, even though it might be visually offset, the space it originally took up remains reserved, and other elements in the +flow will act as if the relatively positioned element hasn't moved. + +**Z-index** + +Relatively positioned elements can also use the z-index property to control their stacking order when they overlap with +other elements. This allows developers to ensure that specific elements appear above or below others. + +## Absolute positioned layout + +When a box's position property set to absolute, an element with this setting is taken out of the document's normal flow. + +This type of positioning is powerful and offers a high level of control over the placement of an element within its +context. + +**Containing Block:** + +One of the most crucial aspects of absolute positioning is understanding its containing block or reference point. + +The containing block for an absolutely positioned element is the nearest positioned ancestor, i.e., an ancestor with its +position set to anything other than static (like relative, absolute, fixed, or sticky). + +If no positioned ancestor exists, the containing block defaults to the initial containing block, which is typically the +viewport. + +Here's a basic implementation using absolute positioning: + +**HTML:** + +```html + +
This div element has position: relative; +
This div element has position: absolute;
+
+``` + +```css +div.relative { + position: relative; + width: 400px; + height: 200px; + border: 3px solid #73AD21; +} + +div.absolute { + position: absolute; + top: 80px; + right: 0; + width: 200px; + height: 100px; + border: 3px solid #73AD21; +} +``` + +**No Space Reservation:** + +When an element is positioned absolutely, it is removed from the normal flow of the document. This means it doesn't +occupy space where it originally was, and other elements will position themselves as if the absolutely positioned +element doesn't exist. + +**Z-index:** + +Absolutely positioned elements can overlap other elements. To control the stacking order of these overlaps, you can use +the z-index property. Higher values of z-index mean the element will appear above those with lower values. + +## Fixed positioned layout + +The "fixed positioned layout" pertains to elements that have their position property set to fixed. Elements with fixed +positioning are removed from the document's normal flow and are positioned relative to the viewport. This means that +they stay in the same position on the screen, even if the rest of the page is scrolled. + +For instance, if you have: + +```css +.fixed-element { + position: fixed; + top: 10px; + right: 15px; +} + +``` + +The .fixed-element will always be 10 pixels from the top and 15 pixels from the right edge of the viewport, regardless +of scrolling. + +**Removed from the Normal Flow:** + +Elements with fixed positioning don't take up space in the document layout. They essentially "float" above the content. +This means other content will flow and position itself as if the fixed positioned element doesn't exist. + +**Z-Index:** + +Since fixed positioned elements can float above other content, you might need to use the z-index property to control the +stacking order when there's an overlap. Higher values of z-index will ensure the element appears above those with lower +values. + +## Sticky positioned layout + +The "sticky positioned layout" pertains to elements that have their position property set to sticky. + +This unique positioning type is a hybrid between relative and fixed positioning. + +A sticky element toggles between relative and fixed, depending on the scroll position. + +It is positioned based on the user's scroll position and can "stick" when it hits the top, bottom, or any side of the +viewport. + +**Containing Block:** + ++ For an element to have a sticky position effectively, its parent container (or the containing block) must have a + defined height. The sticky element will remain within the confines of this container, even when it's sticking. ++ If the container is too tall (or doesn't constrain the sticky element's movement enough), the sticky effect might not + be apparent because the element might never meet the specified threshold. + +**Interactions with Overflow:** + +The value of the overflow property on parent elements can affect sticky positioning. + +If any ancestor has overflow set to hidden, scroll, or auto and the box isn't a scroll container, then the position: +sticky will not work as expected. + +**Example:** + +Here's a basic example of a sticky header: + +```css +.sticky-header { + position: sticky; + top: 0; /* Will start sticking at the top of the viewport */ + background-color: #333; + color: white; + padding: 10px; + z-index: 100; /* to ensure it's on top of other content */ +} +``` + +In this example, as you scroll down a page, the .sticky-header will begin to "stick" to the top of the viewport as soon +as its top edge touches the top of the viewport, and it will remain "stuck" in that position as you continue to scroll +until its parent container is completely out of view. + +Sticky positioning offers an elegant way to enhance user interfaces, providing fixed positioning when needed while +respecting the natural document flow. + +## Positioned offset + +Once an element's position property is set to a value other than static, you can use the following properties to define +its position: + ++ top ++ right ++ bottom ++ left + +The values you give to these properties define the "offset" of the element from the reference point defined by the +position property. For instance, with position: absolute; top: 10px; left: 20px;, the element will be placed 10 pixels +from the top and 20 pixels from the left of its containing block. + +## Containing Block + +For positioned elements, the containing block (or reference point) from which they are offset is determined by their +position value: + ++ static and relative: The containing block is formed by the edge of the content box of the nearest block container + ancestor. ++ absolute: The containing block is the nearest positioned ancestor (an element with position set to relative, absolute, + fixed, or sticky). If there's no positioned ancestor, the initial containing block (usually the viewport) is used. ++ fixed: The containing block is established by the viewport. ++ sticky: The containing block depends on the scrolling box in which the sticky positioning is being applied. \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/selectors.md b/website/docs/tutorials/guides-for-web-developer/css_support/selectors.md new file mode 100644 index 0000000000..69b9625353 --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/selectors.md @@ -0,0 +1,281 @@ +--- +sidebar_position: 2 +title: Selectors +--- + +WebF currently supports the following list of selectors: + +1. [Element selectors](#element-selector) +2. [Attribute selectors](#attribute-selector) +3. [Subsets support of pseudo selectors](#subsets-support-of-pseudo-selectors) + +## Element selector + +Elemental selectors are a group of selectors used to match DOM elements. + +### Type (tag name) selector + +The type selector, often referred to as the tag name selector or element selector, in CSS is used to select and style +all elements of a given type (i.e., with a specified tag name) in webf. + +The selector targets elements based on their node (tag) name. For example: + +**HTML structure:** + +```html +

Heading Level 1

+

This is a paragraph.

+

Another paragraph here.

+
A division element.
+``` + +```css +h1 { + color: green; +} + +p { + font-size: 16px; +} +``` + +In the above CSS: + +The h1 type selector selects all `

` elements on the webf page and applies the specified style to them, in this case +setting +their text color to green. + +The p type selector selects all `

` (paragraph) elements on the webf page and sets their font size to 16 pixels. + +### Class selector + +Class selector allows you to select and style elements based on their class attribute. It's a way to apply styles to +elements that share the same class value without targeting all instances of a particular HTML element. The class +selector is prefixed with a period (.) followed by the class name. + +**HTML structure:** + +```html +

This is a main heading

+

This is a highlighted paragraph.

+

This is a regular paragraph.

+``` + +**CSS with class selectors:** + +```css +.headline { + font-size: 24px; +} + +.highlight { + background-color: yellow; +} +``` + +In the above example: + +The .headline class selector targets the `

` element with the class "headline" and applies a font size of 24px to it. + +The .highlight class selector targets the `

` element with the class "highlight" and gives it a yellow background. + +Notice how the regular `

` element without the "highlight" class is unaffected by the .highlight style. + +### ID selector + +The ID selector allows you to select and style a single, unique element based on its id attribute. + +The ID selector is prefixed with a hash (#) followed by the ID value. + +The id attribute in HTML should be unique within a webf page, meaning that each specific ID can only be used once per +webf page. +This uniqueness differentiates the ID selector from class selectors, which can be applied to multiple elements on a +webf page. + +**HTML structure:** + +```html + +

+

This is an introductory paragraph.

+``` + +**CSS with ID selectors:** + +```css +#header { + background-color: blue; + color: white; +} + +#intro { + font-weight: bold; +} +``` + +in the above example: + +The #header ID selector targets the `
` element with the ID of "header" and applies a blue background and white text +color to it. + +The #intro ID selector targets the `

` element with the ID of "intro" and makes its text bold. + +## Attribute selector + +Attribute selectors in CSS are used to select elements based on their attributes and their attribute values. This allows +for more specific targeting of elements based on attributes rather than just their type, class, or ID. + +### Basic attribute selector: + +Selects elements based on the existence of a specific attribute, regardless of its value. + +```css +/* Selects all elements with a "title" attribute */ +[title] { + border: 1px solid black; +} +``` + +### Exact value match: + +Selects elements with a specific attribute and value. + +```css +/* Selects all input elements with a "type" attribute value of "text" */ +input[type="text"] { + background-color: yellow; +} +``` + +### Partial match using *=: + +Selects elements if the attribute value contains a specified substring. + +```css +/* Selects elements with a "class" attribute containing the word "button" */ +[class*="button"] { + font-weight: bold; +} +``` + +### Prefix match using ^=: + +Selects elements if the attribute value starts with a specified substring. + +```css +/* Selects anchor tags with an "href" attribute value starting with "https" */ +a[href^="https"] { + color: green; +} +``` + +### Suffix match using $=: + +Selects elements if the attribute value ends with a specified substring. + +```css +/* Selects anchor tags with an "href" attribute value ending with ".pdf" */ +a[href$=".pdf"] { + font-weight: bold; +} +``` + +### Substring match following a hyphen using |=: + +Selects elements if the attribute value is a list of whitespace-separated values, one of which begins with the specified +substring. + +```css +/* Selects elements with a "lang" attribute value that starts with "en", such as "en" or "en-US" */ +[lang|="en"] { + text-decoration: underline; +} +``` + +### Exact match or whitespace separated value using ~=: + +Selects elements if the attribute value is exactly the specified string or contains the specified string as one of a +whitespace-separated list of words. + +```css +/* Selects elements with a "data-tags" attribute containing the word "featured" */ +[data-tags~="featured"] { + border: 1px solid red; +} +``` + +Attribute selectors can be quite powerful, especially when you need to style elements based on data attributes or other +non-class, non-id attributes. They can be combined with other selectors to achieve more complex selection patterns. + +## Subsets support of pseudo selectors + +WebF provides support for a subset of pseudo-selectors. We are still working on supporting more pseudo-selectors. + +### Pseudo-elements + +In CSS, pseudo-elements are used to style specific parts of an element that cannot be targeted with simple selectors. +They can be thought of as "virtual elements" that don't exist in the document tree but can be styled with CSS. A +pseudo-element is introduced with the :: syntax. + +WebF support the following lists of pseudo-elements: + +1. ::before - Used to insert content before the content of an element. +2. ::after - Used to insert content after the content of an element. + +For example, using ::before and ::after pseudo-elements, you can add decorative content to an element: + +```css +.element::before { + content: "★"; + color: red; +} + +.element::after { + content: "★"; + color: blue; +} + +``` + +The above CSS would add a red star before the content and a blue star after the content of .element. + +It's important to note that while pseudo-elements appear as part of the document when styled, they do not actually exist +in the DOM and therefore cannot be accessed or manipulated using JavaScript. + +### Tree-Structural pseudo-classes + +Tree-structural pseudo-classes in CSS are a subset of pseudo-classes that allow for the selection of elements based on +their position or structure within the document tree (the hierarchy of HTML elements). They help target elements without +the need for adding extra classes or IDs based on their relationship to other elements. + +WebF support the following lists of pseudo-classes: + +1. :root - Matches the root element of a document, typically the `` element. +2. :nth-child(n) - Matches an element that is the nth child of its parent. +3. :nth-last-child(n) - Matches an element that is the nth child of its parent, counting from the last child. +4. :nth-of-type(n) - Matches an element that is the nth of its type within its parent. +5. :nth-last-of-type(n) - Matches an element that is the nth of its type within its parent, counting from the last + child. +6. :first-child - Matches an element that is the first child of its parent. +7. :last-child - Matches an element that is the last child of its parent. +8. :first-of-type - Matches the first element of its type within its parent. +9. :last-of-type - Matches the last element of its type within its parent. +10. :only-child - Matches an element that is the only child of its parent. +11. :only-of-type - Matches an element that is the only one of its type within its parent. + +Example usage: + +```css +/* Style all

elements that are the first child of their parent */ +p:first-child { + font-weight: bold; +} + +/* Style all

  • elements that are odd-numbered children of their parent */ +li:nth-child(odd) { + background-color: #f5f5f5; +} +``` + +Tree-structural pseudo-classes are especially useful when styling complex layouts or when working with lists, +and other elements where the position of a child relative to its parent or siblings matters. \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/sizing_items.md b/website/docs/tutorials/guides-for-web-developer/css_support/sizing_items.md new file mode 100644 index 0000000000..5b99b83cbc --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/sizing_items.md @@ -0,0 +1,130 @@ +--- +sidebar_position: 6 +title: Sizing Items +--- + +Sizing items refers to setting the width, height, and sometimes the depth of elements. + +There are various properties and units you can use to size items, and the method you choose often depends on the context +and the design requirements. + +## How to set the size for a element + +### Width and Height + +The primary properties to set the size of an element are width and height. + +```css +div { + width: 300px; + height: 150px; +} +``` + +### Units + +There are several units you can use to define sizes: + +Absolute Units: + ++ px (pixels): A dot on the screen. ++ cm, mm, in, pt, pc: Physical units. Not often used for screen designs because they don't always translate well to + digital displays. + Relative Units: + +Relative Units: + ++ %: Relative to the parent element's size. ++ em: Relative to the font size of the element. ++ rem: Relative to the font size of the root element. ++ vw: 1% of the viewport's width. ++ vh: 1% of the viewport's height. ++ vmin: 1% of the viewport's smaller dimension (either width or height). ++ vmax: 1% of the viewport's larger dimension (either width or height). + +### Min and Max Sizing + +You can also set minimum and maximum widths and heights for elements: + +```css +div { + min-width: 200px; + max-width: 600px; + min-height: 100px; + max-height: 400px; +} +``` + +### Flexbox + +In a flex container, you can control the size of flex items using the flex property or its longhand properties ( +flex-grow, flex-shrink, and flex-basis): + +```css +.flex-item { + flex: 1; /* grow and shrink equally and take up equal space */ +} +``` + +### Object Fit + +For content like images inside an element, you can control how they should be resized: + +```css +img { + width: 300px; + height: 200px; + object-fit: cover; /* Resize the image to cover the element, cropping if necessary */ +} +``` + + +## How intrinsic size affect the box size + +Intrinsic size refers to the natural or default size of an element, without any external styling applied. + +For images, the intrinsic size is the actual width and height of the image in pixels as it was created. + +### No Width or Height Specified + +If you don't specify a width or height for an image in your CSS or HTML, the image will display at its intrinsic size. + +This means the box size will be exactly the same as the image's natural width and height. + +```html +Description +``` + +If image.jpg is 500x300 pixels, the image will take up a 500x300 pixel space on the page. + +### Specified Width, No Height + +If you specify a width but no height for an image, the height will auto-adjust to maintain the image's aspect ratio. + +```html +Description +``` + +If the intrinsic size of image.jpg is 500x300 pixels, the rendered image will be 250x150 pixels to maintain the same aspect ratio. + +### Specified Height, No Width + +Similarly, if you specify a height but no width, the width will auto-adjust to maintain the image's aspect ratio. + +### Specified Width and Height + +If you specify both width and height, the image will be resized to those dimensions, potentially breaking the aspect ratio. This can lead to the image looking stretched or squished. + +```html +Description +``` + +This will force the image into a square shape, which can distort its appearance if its intrinsic aspect ratio isn't 1:1. + +### CSS Properties like max-width: The max-width + +The max-width property can also affect the box size of an image. + +If an image has an intrinsic width of 500 pixels but is inside a container that has max-width: 300px; the image will not exceed 300 pixels in width. + +If the height isn't specified, it will scale proportionally. \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/styling_text_and_font.md b/website/docs/tutorials/guides-for-web-developer/css_support/styling_text_and_font.md new file mode 100644 index 0000000000..0de389713e --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/styling_text_and_font.md @@ -0,0 +1,152 @@ +--- +sidebar_position: 4 +title: Styling Text and Fonts +--- + +## Styling text + +Text broad category of properties and values that deal with the styling and arrangement of textual content within a +webf/web document. + +These properties allow you to adjust the appearance and layout of text elements. + +1. text-align: + + Specifies the horizontal alignment of text. + + Values: left, right, center, justify. + ```css + p { + text-align: center; + } + ``` +2. text-decoration: + + Specifies the decoration added to text. + + Values: none, underline, overline, line-through. + ```css + a { + text-decoration: none; /* Typically used to remove underlines from hyperlinks */ + } + ``` +3. word-spacing: + + Specifies the space between words. + + ```css + p { + word-spacing: 1em; + } + ``` +4. white-space: + + Specifies how whitespace inside an element is handled. + + Values: normal, nowrap, pre, pre-line, pre-wrap. + ```css + pre { + white-space: pre; /* Preserves whitespace and newlines */ + } + ``` +5. text-shadow: + + Applies a shadow to text. + + Requires horizontal shadow, vertical shadow, and color values. Optional: blur radius. + + ```css + h1 { + text-shadow: 2px 2px 4px #000; + } + ``` +6. text-overflow: ++ Specifies how overflowed content that is not displayed should be signaled to the user. ++ Values: clip, ellipsis, fade. + + ```css + p { + text-overflow: ellipsis; + } + ``` + +## Font + +Fonts allowing developers to specify and manipulate font styles. Here's an overview of how fonts supported in webf: + +1. Font-Family: + The font-family property specifies which font should be used for text within an element. It can be a specific font + like "Arial", or a generic font family like sans-serif. + + ```css + p { + font-family: "Times New Roman", Times, serif; +} + ``` + +It's common to provide multiple font families as fallbacks. If the webf does not support the first font, it tries the +next font in the list. + +2. Font-Size: + The font-size property sets the size of the font. + + ```css + h1 { + font-size: 2em; +} + ``` + +You can use units like px, em, rem, %, vw, etc. to specify font sizes. + +3. Font-Weight: + The font-weight property defines the thickness of the characters in a font. + + ```css + strong { + font-weight: bold; +} + ``` + +Acceptable values include normal, bold, bolder, lighter, and numbers from 100 to 900. + +4. Font-Style: + The font-style property is used to define if the font should be italic or not. + + ```css + em { + font-style: italic; +} + ``` + +Common values include normal, italic. + +5. Line-Height: + The line-height property specifies the height of a line and can help improve text readability. + + ```css + p { + line-height: 1.5; +} + ``` + +6. @font-face: + + The @font-face rule allows custom fonts to be loaded on a webpage. This rule must be followed by a set of descriptors + that define the font's style and the URI of the font file. + + ```css + @font-face { + font-family: "MyCustomFont"; + src: url("path/to/font.otf") format("otf"); +} + ``` + +WebF supports the following font formats: + + ``` + 1. .ttc + 2. .ttf + 3. .otf + ``` + +WebF does not support .woff and .woff2 fonts. + +7. Font Shorthand: + The font property is a shorthand property for setting font-style, font-variant, font-weight, font-size, line-height, + and font-family all at once. + ```css + p { + font: italic bold 1em/1.5 "Arial", sans-serif; +} + ``` \ No newline at end of file diff --git a/website/docs/tutorials/guides-for-web-developer/css_support/the_box_model.md b/website/docs/tutorials/guides-for-web-developer/css_support/the_box_model.md new file mode 100644 index 0000000000..051da47e6a --- /dev/null +++ b/website/docs/tutorials/guides-for-web-developer/css_support/the_box_model.md @@ -0,0 +1,126 @@ +--- +sidebar_position: 4 +title: The Box Model +--- + +The Visual Formatting Model in CSS is a fundamental concept that describes how webf and browser process and +display document content. It encompasses the rules and behaviors used to determine the layout of elements on the screen. + +## The Box Model + +The box model in CSS describes the layout and design properties of elements as rectangular boxes, detailing how they are +sized, padded, bordered, and margined. The box model is fundamental to understanding how space is +managed and elements are displayed in webf/web design. + +Each box in the box model consists of the following components, from the innermost to the outermost: + +1. Content: This is the main content of the box, where text, images, or other media are displayed. The dimensions of the + content box can be controlled using the width and height properties. + +2. Padding: This is the space between the content of the box and its border. Padding does not have any color by default, + but it will show the background color of the box. You can control padding with properties like padding-top, + padding-right, padding-bottom, and padding-left or the shorthand padding. + +3. Border: This is a potentially visible boundary around the padding and content. It can have a style, width, and color. + The border is controlled with properties like border-style, border-width, border-color, and their specific variations + for each side (e.g., border-top-width). + +4. Margin: This is the outermost layer of the box, and it represents the space between the box's border and the + neighboring + elements. Margin is transparent and doesn't show any color, not even the background color of the element. You can + control the margin with properties like margin-top, margin-right, margin-bottom, and margin-left or the shorthand + margin. + +The following diagram shows how these areas relate and the terminology used to refer to the various parts of the box: + +![img](./imgs/box_model.png) + +One important concept to understand with the box model is the box-sizing property: + ++ content-box: The width and height properties set the size of the content box, not including padding and + border. + ++ border-box (default for webf): The width and height properties include content, padding, and border, but not the + margin. + +:::caution + +From now on, WebF only supports the `box-sizing: border-box` mode. Setting the `box-sizing` property to `content-box` +will have no effect until WebF is released with `content-box` support. + +::: + +Here is a example to show how border-box works with the following styles: + +```css +div { + width: 300px; + height: 150px; + padding: 10px; + border: 5px solid black; + box-sizing: border-box; +} +``` + +With box-sizing: border-box, the actual content area of the div will be: + ++ Width: 300px - 10px (left padding) - 10px (right padding) - 5px (left border) - 5px (right border) = 270px ++ Height: 150px - 10px (top padding) - 10px (bottom padding) - 5px (top border) - 5px (bottom border) = 120px + +So, the content area will be 270px wide and 120px tall, but the overall dimensions of the div (including padding and +border) will remain 300px by 150px. + +## Types of Boxes + +In CSS, every element generates a box when rendered on the screen. These boxes define the layout and look of elements on +the page. The type of box an element generates and its characteristics are primarily determined by the display property +of the element. + +Here's a detailed look at the various types of boxes that WebF provides: + +1. **Block-level Boxes**: + +* Generated by block-level elements. +* Stack vertically, one after another. +* Occupy the full width of their containing element by default. +* Respects box model properties: `margin`, `border`, `padding`, `width`, and `height`. +* Examples: `
    `, `

    `, `

    `, `