Open ngocminhxx opened 3 years ago
Dạ, e cảm ơn.
On Sun, Dec 13, 2020, 11:30 ngocminhxx notifications@github.com wrote:
[image: image] https://user-images.githubusercontent.com/8384796/102003170-6a8bb080-3d36-11eb-8ca7-af536d808bae.png
[image: image] https://user-images.githubusercontent.com/8384796/102003172-75464580-3d36-11eb-88ba-19300a685942.png
[image: image] https://user-images.githubusercontent.com/8384796/102003174-79726300-3d36-11eb-8d6b-7a08255c114e.png
Em có thời gian thì hãy cải thiện thêm những trường hợp như thế này nha, em có thể nghiên cứu thêm về css gradient background
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/TranTLy/css-exercise/issues/1, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGAPMCJRQUOAXAMOOGZSRM3SUQ7ORANCNFSM4UZCX3NA .
Fix #1
Cám ơn em nha, mai có thời gian anh sẽ review nhé ^^
Hi em, anh đã em qua code của em, anh có vài góp ý và câu hỏi, khi nào có thời gian em hãy trả lời anh nha:
.btn-red-with-arrow { position: relative; width: 250px; height: 50px; padding: 10px 40px; margin-bottom: 0; color: #fff; font-size: 14px; font-weight: bold; background-color: red; }
.btn-red-with-arrow:before, .btn-red-with-arrow:after { position: absolute; top: 0; bottom: 0; margin-top: auto; margin-bottom: auto; content: ''; box-sizing: border-box; }
.btn-red-with-arrow:before { right: 20px; width: 18px; height: 18px; border: 2px solid #fff; border-radius: 50%; }
.btn-red-with-arrow:after { right: 27px; width: 5px; height: 5px; border-top: 2px solid #fff; border-right: 2px solid #fff; transform: rotate(45deg); }
.icon-cross { position: relative; width: 50px; height: 50px; margin-bottom: 60px; background-color: blue; }
.icon-cross:before, .icon-cross:after { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 5px; height: 25px; margin: auto; background-color: #fff; content: ""; }
.icon-cross:after { transform: rotate(90deg); }
Cảm ơn a đã dành thời gian review, gửi câu hỏi và code mẫu cho e. E sẽ trả lời a sớm ạ. E cảm ơn.
1. Prefix trong css
Prefix trong CSS là tiền tố được thêm vào thuộc tính CSS, giúp các trình duyệt khác nhau có thể hiểu được.
Một số prefix: -webkit-, -moz-, -o-, -ms-
Có thể sử dụng trang web này https://caniuse.com để kiểm tra xem thuộc tính đó được hỗ trợ bởi những trình duyệt nào, version nào cần dùng prefix, version nào ko cần dùng prefix.
Cần dùng prefix vì một số thuộc tính CSS đang ở giai đoạn thử nghiệm, thêm prefix thì trình duyệt tương ứng sẽ hiểu, còn những trình duyệt khác sẽ xem đó là thuộc tính sai và bỏ qua.
Trong bài e dùng -webkit-text-stroke, nhưng e thiếu prefix cho các trình duyệt khác :(
2. box-sizing
3. "Em có biet sử dụng SCSS hay SASS không?"
4. "Em thấy việc include nhiều css vào 1 page và include 1 file css vào 1 page, cái nào tiện lợi hơn, và tại sao?" Em thấy include nhiều file css vào 1 page tiện lợi hơn vì:
5. (Code example)
6. "Đặt tên cho một element như div 1 cái ID hoặc class nhưng lại không sử dụng đến ID hoặc class đó"
Theo e hiểu, class name và ID của 1 element được dùng để style CSS và handle element với JS.
Các element cũng có thể được style bằng tag name.
Nếu không sử dụng đến class name và ID thì những phần này xem như là code dư.
Tuy nhiên, theo e, class name và ID cũng có thể được xem là comment của code, giúp người dùng đọc vào hiểu được element đó dùng để làm gì. Và việc đặt tên sẵn class name, id cũng giúp mình extend dễ hơn sau này. Ví dụ style cho 1 element đã có trước đó, nhưng chưa có code CSS trong code cũ. Thay vì phải xem lại context, và các element có liên quan để đặt class name/ID cho phù hợp thì mình đã có sẵn class name/ID, chỉ cần lấy ra sử dụng.
Nhưng không nên đặt quá nhiều class name/ID mà không sử dụng đến, điều này làm cho việc maintain code rất khó.
. .
Cảm ơn anh đã dành thời gian xem câu trả lời của e nha. Câu trả lời của e còn nhiều chỗ thiếu sót, khi nào có thời gian, anh review giúp e nhé. Cảm ơn anh ạ.
Bình thường đối với những trang chỉ có HTML và CSS thôi thì không cần sử dụng thêm class name hay ID, em có thể miêu tả chức năng bằng cách đặt tên cho class ấy luôn/. Ví dụ, .btn.btn-red, người ta sẽ hiểu rằng đó là 1 cái button với miêu tả là button màu đỏ vì đã có .btn-red. Nếu chỉ là button default thôi, em thêm extend .btn-red nhưng chưa sử dụng class .btn-red thì có thể gây confused cho coder khác vì btn-red mặc định được hiểu là 1 CÁI NÚT MÀU ĐỎ nhưng lại không giống, có thể họ sẽ tìm cách debug cái nút đó xem sai chỗ nào nhưng thực ra class btn-red đó chỉ là để sẵn và không (hoặc chưa) dùng tới. Nếu em muốn comment, em nên sử dụng comment out trong code, anh nghĩ không nên sử dụng class name như một cách 1 commnet, có thể gây hiểu lầm hoặc lỗi code ngoài ý muốn. Class hoặc IDs chưa được sử dụng đó có thể sau này không cần sử dụng luôn hoặc em quên mà lại đăt thêm 1 class name hay IDs khác nữa thì lại tốn thời gian
Về phần prefix em có thể dùng tool để tự nó generate ra tự động, em không cần nhớ bởi vì nó nhiều lắm, không nhớ nổi đâu. Thường nếu dùng tool thì có 2 cách, 1 là tự động, hai là manual, em có thể tìm cho anh vài tool được không?
Sau này nếu em muốn đi sâu vào lập trình web, em cần sử dụng SCSS nhiều hơn vì nó nhanh và dễ debug hơn, em có thể nghiên cứu qua gulp để tự động compile SCSS sang CSS và auto add prefix nữa, rất tiện lợi. Nếu cần gì hỏi thì em cứ hỏi hen
E cảm ơn a nhé.
E sẽ note lại comment của a để cải thiện thêm (
Auto prefix:
Cảm ơn a đã giới thiệu Gulp, e sẽ tìm hiểu thêm về nó.
E muốn hỏi thêm, để tìm hiểu về những trang có animation giống như vầy https://bruno-simon.com, e cần bắt đầu từ đâu? A có thể cho e biết một số keyword cần thiết để bắt đầu tìm hiểu dc ko ạ?
Cảm ơn a đã dành thời gian ạ.
Trang này nó sử dụng html canvas và js để tạo ra như 1 game vậy, css animation ko handle được nhiều trong trang này. Không biết em có học js và jquery chưa, lúc đó em có thể handle key up và key down để điều khiển cái xe di chuyển, sử dụng event on click để handle click chuột. Cơ bản là vậy, còn về hình ảnh thì anh không rành lắm tại vì biết rất ít về canvas, bth chỉ export từ file thiết kế như AI hoặc XD, chứ chưa bao giờ tự vẽ bằng canvas. Nếu được, em có thể tự tìm hiểu cơ bản trước bằng https://www.w3schools.com/html/html5_canvas.asp https://www.digitaldesignjournal.com/html5-canvas-drawing-tools/
Có nhiều tool hỗ trợ vẽ canvas từ 2d đến 3d luôn, tuy nhiên em phải đi sâu vào và tốn thời gian nhiều cho nó nếu em muốn đi chuyên sau. Về cơ bản, làm web thì hiếm lắm mới đụng phải những trang như cái trang này https://bruno-simon.com/
Visual Code có ext để tự generate ra webkit in code luôn, còn grunt hoặc gulp sẽ giúp em tạo prefix khi em compile scss ra css. Nói chung, khi em sử dụng tool compile thì em ko cần care về prefix vì đã có tụi nó lo hết, cái em cần use là cái file css được tạo ra. Anh thường sử dụng gulp và extension của nó để compile scss và add prefix cho css, ngoài ra em còn có thể add css stylelint nữa, nhiều công dụng lắm
"use strict";
const del = require('del'); const gulp = require('gulp'); const sass = require('gulp-sass'); const postcss = require('gulp-postcss'); const autoprefixer = require('autoprefixer'); const sourcemaps = require('gulp-sourcemaps'); const cleanCss = require('gulp-clean-css'); const notify = require('gulp-notify'); const htmllint = require('gulp-htmllint'); const gutil = require('gulp-util'); const bootlint = require('gulp-bootlint'); const gulpif = require('gulp-if'); const minimist = require('minimist'); const ejs = require('gulp-ejs'); const rename = require("gulp-rename");
const fs = require('fs'); const cleanCssConfig = JSON.parse(fs.readFileSync('./config/cleanCss.config.json'));
/** * **/ const options = minimist(process.argv.slice(2), { string: 'env', default: {env: process.env.NODE_ENV || 'development'} // NODE_ENVに指定がなければ開発モードをデフォルトにする }); const isProduction = (options.env === 'production');// $ gulp --env production
console.log('env is ' + options.env);
/** * **/ const baseDir = './_public/'; const _node_modules_dir = 'node_modules/'; const _htmlDir = baseDir + ''; const _scssDir = [ 'scss/*/.scss', '!' + 'scss/xxx.scss' ]; const _cssDir = baseDir + 'css/'; const componentsDir = baseDir + 'components/';
const htmlFiles = [ _htmlDir + '/*.html', '!' + _node_modules_dir + '*/.html', '!' + componentsDir + '/*.html' ];
let updateSourceTime;
/** * **/ function scss() { const startTime = Date.now();
return gulp.src(_scssDir) .pipe(sourcemaps.init()) .pipe(sass({ outputStyle: 'expanded' })) .pipe(postcss([autoprefixer()])) // .pipe(cleanCss(cleanCssConfig)) // .pipe(gulpif(isProduction, cleanCss())) .pipe(sourcemaps.write('.')) .pipe(gulp.dest(_cssDir)) .pipe(notify({ onLast: true, title: "SCSS build is finished!", message: Date.now() - startTime + ' ms' })); }
/** * **/ function removeHtml() { return del([ _htmlDir + '*/.html' ]); }
/** * **/ function ejsBuild() { return gulp.src([ "_ejs/*/.ejs", "!_ejs/_inc/*.ejs" ]) .pipe(ejs({}, {}, { "ext": ".html" })) .pipe(rename({ extname: ".html" })) .pipe(gulp.dest(baseDir)); }
/** * **/ function htmlLint() { gulp.src(htmlFiles) .pipe(htmllint({ 'config': 'config/.htmllintrc', // "plugins": ['htmllint-spellcheck'], }, htmllintReporter)); }
/** * **/ function htmllintReporter(filepath, issues) { if (issues.length > 0) { issues.forEach(function (issue) { let name = gutil.colors.red('[gulp-htmllint Error] '); let path = gutil.colors.white(filepath + ' [Line: ' + issue.line + ', ' + issue.column + ']: '); let message = issue.msg; let issueCode = gutil.colors.red('(' + issue.code + ') '); let errorMessage = name + path + issueCode + message;
gutil.log(errorMessage);
});
// process.exitCode = 0;
// process.exit(0);
} }
/** * **/ function bootLint() { gulp.src(baseDir + 'index.html') .pipe(bootlint()); }
/** * **/ function watchFiles() { const scssWatcher = gulp.watch( _scssDir, gulp.parallel(scss));
scssWatcher.on('change', function(path, stats) { console.log('scssWatcher: File ' + path + ' was changed'); });
const htmlWatcher = gulp.watch( htmlFiles, gulp.parallel(htmlLint, bootLint));
htmlWatcher.on('change', function(path, stats) { console.log('htmlWatcher: File ' + path + ' was changed'); });
// const ejsWatcher = gulp.watch( // '_ejs/*/.ejs', // gulp.series(removeHtml, ejsBuild)); // // ejsWatcher.on('change', function(path, stats) { // console.log('File ' + path + ' was changed'); // }); }
/** * **/ exports.default = gulp.series(scss, watchFiles);
gulpfile cơ bản của cty anh làm, xem cho vui ^^, nó còn liên quan tới nodejs, npm và yarn
wow, dạ, cảm ơn a nha. E sẽ học thêm, có gì ko hiểu, a cho e hỏi thêm nha.
Khi nào a có thời gian, nếu dc thì a cho e xin thêm bài tập nhé. Cảm ơn a ạ.
^^ khi nào rảnh để anh soạn rồi gửi anh Ân nhé Happy New Year
Dạ, cảm ơn a. A new year is coming, wish you have great things! Happy new year! Cheer ^_^
On Thu, Dec 31, 2020, 22:57 ngocminhxx notifications@github.com wrote:
^^ khi nào rảnh để anh soạn rồi gửi anh Ân nhé Happy New Year
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/TranTLy/css-exercise/issues/1#issuecomment-752993829, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGAPMCKPRTEFGMBHPIXIDW3SXSNN7ANCNFSM4UZCX3NA .
Em có thời gian thì hãy cải thiện thêm những trường hợp như thế này nha, em có thể nghiên cứu thêm về css gradient background